以后每用Runtime解决一个问题,就会记录在这个文集里。
我将以真实的使用场景为大家讲述Runtime的各种用法,让Runtime真正的投入到生产中。
合辑demo Github地址
问题描述
给WKWebView做setContentOffset动画的方式有两种,一种是用setContentOffset:animated:,另一种是其他。
如果对动画效果有特殊的要求,那动画方式就只能选择后者。而如果webView正好被选中而弹出了Menu,那问题就比较暧昧了。可以在滑动的时候直接去掉Menu,那问题还比较简单,但如果需要在滑动结束后再恢复Menu,那问题就尴尬了。另外,如果这个地方不做特殊处理,Menu就会停留在原来的位置。
当然,使用setContentOffset:animated:是没这个问题的。WKWebView会在内部处理这种情况。它会在动画开始的时候消失Menu,在动画结束后再展示出Menu。
那怎么在使用自定义方法实现动画的同时又避免这个坑呢?我试着解决了这个问题。
问题原因
其实解决这个问题并没有花多少时间,在之前我已经对UIMenuController的底层实现比较了解,所以我在Menu消失和出现的方法上下了断点,很轻松的就找到了原因。
使用setContentOffset:animated:做动画,会在开始动画的时候,给WKContentView发了_willStartScrollingOrZooming消息。在动画结束后又发了_didEndScrollingOrZooming消息。方法中实现了消失和展示Menu的相关逻辑。而用其他的方式做动画并没有上诉流程。
解决方法
解决的办法比较简单,在自定义动画开始和结束时,也调一下这两个方法,问题就解决了。这两个方法无参数也无返回值,比较干净,可以放心调用,代码大概如下。
@implementation WKWebView (ScrollAnimateSupport)
[self.scrollView.subviews.firstObject performSelector:NSSelectorFromString(@"_didEndScrollingOrZooming")];
[self.scrollView.subviews.firstObject performSelector:NSSelectorFromString(@"_didEndScrollingOrZooming")];
@end