- 问题描述:一个详情界面,上部分为WKWebView,下部分为UItableView,webview展示详情界面内容,tableVIew展示详情相关推荐列表!
- 实现要求:webView与tableView连贯且滑动时不能有卡顿或者出现手势冲突的问题!
- 首先大家会想到使用tableview,将webView放在cell或者TableHeaderView,这些都是可以的,但是唯一的难点就是怎么获取到webView的高度,让cell或者TableHeaderView的高度适应,才能完整的展示webview!!!
我们的思路:
-
1.在控制器view上先添加一个UIScrollView,宽度为屏幕宽度,高度为view显示可滑动区域的高,这里设置为A(下面有使用到),然后在scrollView上添加一个UIView : viewA ,viewA的高度为2A,宽度为屏幕宽度!然后,在viewA的上半部添加我们的webview,下半部添加tableView!
-
2.添加两个监听
[self.webView addObserver:self forKeyPath:@"scrollView.contentSize" options:NSKeyValueObservingOptionNew context:nil]; [self.tableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
-
3.实现监听方法
//{ //CGFloat _webViewContentHeight;//webview的content高度,有改变时,将实际的_webView.scrollView.contentSize.height赋值给它 //CGFloat _tableViewContentHeight;//tableView的content高度,有改变时,_tableView.contentSize.height赋值给它 //} - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == _webView && [keyPath isEqualToString:@"scrollView.contentSize"] && _webViewContentHeight != _webView.scrollView.contentSize.height) { _webViewContentHeight = _webView.scrollView.contentSize.height; [self updateContainerScrollViewContentSize]; } else if (object == _tableView && [keyPath isEqualToString:@"contentSize"] && _tableViewContentHeight != _tableView.contentSize.height ) { _tableViewContentHeight = _tableView.contentSize.height; [self updateContainerScrollViewContentSize]; } }
-
4.updateContainerScrollViewContentSize 根据WebView和tableView的ContentSize变化,调整scrollView的contentSize以及webview和tableView的高度、位置展示的区域
- (void)updateContainerScrollViewContentSize { self.containerScrollView.contentSize = CGSizeMake(self.view.width, _webViewContentHeight + _tableViewContentHeight); //如果内容不满一屏,则webView、tableView高度为内容高,超过一屏则最大高为一屏高 CGFloat webViewHeight = (_webViewContentHeight < A) ? _webViewContentHeight : A; CGFloat tableViewHeight = (_tableViewContentHeight < A) ? _tableViewContentHeight : A; //更新webview和tableView父view:viewA的高度 self.viewA.height = webViewHeight + tableViewHeight; self.webView.height = webViewHeight <= 0.1 ?0.1 :webViewHeight; self.tableView.height = tableViewHeight; self.tableView.top = self.webView.height; //更新展示区域 [self scrollViewDidScroll:self.scrollView]; }
-
5.更新viewA的top位置以及webview.scrollView和tableView的contentOffset
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ if (_containerScrollView != scrollView) { return; } CGFloat offsetY = scrollView.contentOffset.y; CGFloat webViewHeight = self.webView.height; CGFloat tableViewHeight = self.tableView.height; if (offsetY <= 0) { //顶部下拉 self.viewA.top = 0; self.webView.scrollView.contentOffset = CGPointZero; self.tableView.contentOffset = CGPointZero; } else if (offsetY < _webViewContentHeight - webViewHeight) { //scrollView偏移量的展示范围还在webView的最大偏移量内容区域里 //viewA相对位置保持不动,调整webView的contentOffset self.viewA.top = offsetY; self.webView.scrollView.contentOffset = CGPointMake(0, offsetY); self.tableView.contentOffset = CGPointZero; } else if(offsetY < _webViewContentHeight) { //webView滑到了底部,开始展示tableView的内容 self.viewA.top = _webViewContentHeight - webViewHeight; self.webView.scrollView.contentOffset = CGPointMake(0, _webViewContentHeight - webViewHeight); self.tableView.contentOffset = CGPointZero; } else if(offsetY < _webViewContentHeight + _tableViewContentHeight - tableViewHeight) { //scrollView偏移量的展示范围到达tableView的最大偏移量内容区域 //调整tableView的contentOffset self.viewA.top = offsetY - webViewHeight; self.tableView.contentOffset = CGPointMake(0, offsetY - _webViewContentHeight); self.webView.scrollView.contentOffset = CGPointMake(0, _webViewContentHeight - webViewHeight); } else if(offsetY <= _webViewContentHeight + _tableViewContentHeight ) { //tableView滑到了底部 self.viewA.top = self.containerScrollView.contentSize.height - self.contentView.height; self.webView.scrollView.contentOffset = CGPointMake(0, _webViewContentHeight - webViewHeight); self.tableView.contentOffset = CGPointMake(0, _tableViewContentHeight - tableViewHeight); } }
-
6.最后不要忘记移除监听
[self.webView removeObserver:self forKeyPath:@"scrollView.contentSize"]; [self.tableView removeObserver:self forKeyPath:@"contentSize"];