我們總會遇見特別不適合使用原生開發(fā)的頁面,比如一個文章詳情頁,上面是文章下面是評論,就比如現在用的簡書的手機版這樣,那么這種需求應該怎么做呢?
最好的方法當然是整個頁面都是用H5開發(fā),哈哈哈;當然下面評論有時候會有很多交互導致得用原生控件開發(fā),那這里就面臨著嚴峻的問題了,上面是網頁可以滑動,下面是評論最好是用列表做,具體怎么組合起來就值得我們說道說道了,當然方法有很多種,我這里講解一種我覺得各方面都不錯的。
ps:問題總結起來還是兩個滑動視圖上下滑動問題所以用我之前講解的多個滑動視圖沖突解決http://www.itdecent.cn/p/cfe517ce437b 也可以解決不過這樣使用H5那面配合的地方比較多。這個不多說,下面介紹我們今天要說的。
這個方案的整體思路:把web和table同時加在一個底層ScrollView上面,滑動底層ScrollView同時不斷控制web和table的偏移量位置,使頁面看起來是兩個滑動視圖連在一起的。

一,視圖介紹
黃色的是底層ScrollView,青色的一個加在底層ScrollView上的view(這里我們叫它contentView),然后正加載簡書網頁的是web,紅色部分是table。web和table再加contentView上,這樣我們控制整體位置的時候使用contentView就行;
二,視圖之間的高度關系:
web和table的最大高度都是底層ScrollView的高度,這樣做可以正好讓其中一個充滿整個底層ScrollView。
contentView的高度是web和table高度的和(畢竟就是為了放他們兩)。
底層ScrollView的可滑動高度這里設定成web和table可滑動高度的總和,方便滑動處理。
ps:具體代碼在后面。
三,滑動處理思路
滑動都靠底層ScrollView,禁用web和table的滑動,上面說了底層ScrollView的可滑動高度是web和table的總和所以進度條是正常的。
然后在滑動的同時不斷調整contentView的位置,web和table的偏移量,使頁面效果看起來符合預期。
四,滑動處理具體操作,整個滑動可以分成五階段。ps:offsety 底層ScrollView的偏移量
1.offsety<=0,不用過多操作正常滑動
2.web內部可以滑動。控制contentView懸浮,使web在屏幕可視區(qū)域。同時修改web的偏移量。
3.web滑動到頭。保持contentView的位置和web的偏移量,使table滑動到屏幕可視區(qū)域
4.table內部可以滑動。控制contentView懸浮,使table在屏幕可視區(qū)域。同時修改table的偏移量。
5.table滑動到頭。保持contentView的位置和table的偏移量,使頁面滑動到底部
四,具體代碼
1.因為web和table都是隨內容變高的,這里選擇通過監(jiān)聽兩者高度變化,同時刷新各個控件的高度,對應第二步驟
//添加監(jiān)聽
[self.webView addObserver:self forKeyPath:@"scrollView.contentSize" options:NSKeyValueObservingOptionNew context:nil];
[self.collectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
//刷新各個控件高度
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if (object == _webView) {
if ([keyPath isEqualToString:@"scrollView.contentSize"]) {
[self updateContainerScrollViewHeight];
}
}else if(object == _collectionView) {
if ([keyPath isEqualToString:@"contentSize"]) {
[self updateContainerScrollViewHeight];
}
}
}
- (void)updateContainerScrollViewHeight{
CGFloat webViewContentHeight = self.webView.scrollView.contentSize.height;
CGFloat collectionContentHeight = self.collectionView.contentSize.height;
if (webViewContentHeight == _lastWebViewContentHeight && collectionContentHeight == _lastCollectionContentHeight) {
return;
}
_lastWebViewContentHeight = webViewContentHeight;
_lastCollectionContentHeight = collectionContentHeight;
self.containerScrollView.contentSize = CGSizeMake(self.view.width, webViewContentHeight + collectionContentHeight);
CGFloat webViewHeight = (webViewContentHeight < _contentHeight) ?webViewContentHeight :_contentHeight;
CGFloat collectionHeight = collectionContentHeight < _contentHeight ?collectionContentHeight :_contentHeight;
self.webView.height = webViewHeight <= 0.1 ?0.1 :webViewHeight;
self.contentView.height = webViewHeight + collectionHeight;
self.collectionView.height = collectionHeight;
self.collectionView.top = self.webView.bottom;
[self scrollViewDidScroll:self.containerScrollView];
}
2.具體滑動處理代碼
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (_containerScrollView != scrollView) {
return;
}
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat webViewHeight = self.webView.height;
CGFloat collectionHeight = self.collectionView.height;
CGFloat webViewContentHeight = self.webView.scrollView.contentSize.height;
CGFloat collectionContentHeight = self.collectionView.contentSize.height;
if (offsetY <= 0) {
self.contentView.top = 0;
self.webView.scrollView.contentOffset = CGPointZero;
self.collectionView.contentOffset = CGPointZero;
}else if(offsetY < webViewContentHeight - webViewHeight){
self.contentView.top = offsetY;
self.webView.scrollView.contentOffset = CGPointMake(0, offsetY);
self.collectionView.contentOffset = CGPointZero;
}else if(offsetY < webViewContentHeight){
self.contentView.top = webViewContentHeight - webViewHeight;
self.webView.scrollView.contentOffset = CGPointMake(0, webViewContentHeight - webViewHeight);
self.collectionView.contentOffset = CGPointZero;
}else if(offsetY < webViewContentHeight + collectionContentHeight - collectionHeight){
self.contentView.top = offsetY - webViewHeight;
self.collectionView.contentOffset = CGPointMake(0, offsetY - webViewContentHeight);
self.webView.scrollView.contentOffset = CGPointMake(0, webViewContentHeight - webViewHeight);
}else if(offsetY <= webViewContentHeight + collectionContentHeight ){
self.contentView.top = self.containerScrollView.contentSize.height - self.contentView.height;
self.webView.scrollView.contentOffset = CGPointMake(0, webViewContentHeight - webViewHeight);
self.collectionView.contentOffset = CGPointMake(0, collectionContentHeight - collectionHeight);
}else {
//do nothing
NSLog(@"do nothing");
}
}
打完收工。