常常看到一些场景下用UIWebView
都是嵌套的. 但UIWebView
本身有个UIScrollView
的属性.这个scrollView
上面放了个子视图充当浏览器.这使得他嵌套与其他UIScrollView
的时候会异常的麻烦.
我们看看烦在什么地方?
一般别人都用UITableViewCell
里面放UIWebView
用UIWebViewDelegate
中didStart
第一次加载时回调.设置一次初始高度
用didFinish
加载完成计算最终高度. 通过传参数把高度传到当前Controller
然后刷新UITableView
的高度.
注意的坑点在于,在didFinish
要记得终结掉webView
和Controller
的回调了.不然会无止境load
.页面一直跳跳跳
是的. 以上情况80%的html
网页能解决. 但它不是一个万金油的方案. 你不能保证h5
不进行动态加载. 它并不会在webViewDidFinish
算出最终高度(这个原因和这个html
页面有关.它在滑动后再加出来一段高度.即网页会滚动加载). 也就是说这个高度是不准确的. 而且如果我在UIWebView
里面需要跳转. 不同页面需要刷新不同高度 . 种种变化使得这种方式本身逻辑就非常复杂. 牵涉的线过多.无意义的繁琐.
于是我找到一个解决方案,觉得不错
避开两个UIScrollview
嵌套. 其实苹果官方说过尽量不要用到UIScrollview
嵌套. 因为你想. 当UIScrollview
滑动. 大家都触发delegate
. scrollViewDidScroll
方法里谁知道谁在动? 所以上来先要判断一下到底是谁动了, 再一个,我还需要控制一个能动, 另一个不能动. 滚动到一个位置,一个不能动,另一个让他能动. 这种用多个scrollView
嵌套肯定是不合理的 . 当然硬做也能做. 如果你是聪明人,效率第一,蠢的方法不要去用.蠢的路不要去走.
正解如下
我们只在UIWebView
里做文章. UIWebView
高度定为一屏幕. 这样就完美避开上面的问题.
UIWebView.scrollView
里有一个子视图是专门用来充当浏览器的.获取它.调整位置.上方放一个HeaderView
. HeaderView
你可以自定义. 我这里就点到为止了.
这里面还有一个坑. 假如你要去监听contentoffset告诉外面的人,什么时候做什么事情, 通常回想起scrollViewDelegate
然而当你调用UIScrollviewDelegte
中的didScroll
方法时. 你发现屏幕外的图片居然不load了. 真是R了狗了 ??.
不过没关系. 我们还有KVO
. 对ScrollView
添加contentoffset
的观察者. (注意处理生命周期).
其次. KVO
的监听回调方法要记得判断是否是对contentoffset
的监听. 因为系统会有很多的KVO
.是你看不到的, 所以你需要对其他那些看不到的Observer
返回父类方法(多态). 如果你不这么做. 屏幕以外的图片依然加载不出来 . 呵呵哒 .
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:@"contentOffset"]) {
CGFloat offset = self.scrollView.contentOffset.y;
[self animationForScroll:offset];
if (offset > xxx) {
// do sth ...
}
else {
// do sth ...
}
}
else {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context] ;
}
}
demo简单效果
123.gif
项目优化后效果
123321.gif