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

一,視圖介紹
黃色的是底層ScrollView,青色的一個(gè)加在底層ScrollView上的view(這里我們叫它c(diǎn)ontentView),然后正加載簡(jiǎn)書網(wǎng)頁的是web,紅色部分是table。web和table再加contentView上,這樣我們控制整體位置的時(shí)候使用contentView就行;
二,視圖之間的高度關(guān)系:
web和table的最大高度都是底層ScrollView的高度,這樣做可以正好讓其中一個(gè)充滿整個(gè)底層ScrollView。
contentView的高度是web和table高度的和(畢竟就是為了放他們兩)。
底層ScrollView的可滑動(dòng)高度這里設(shè)定成web和table可滑動(dòng)高度的總和,方便滑動(dòng)處理。
ps:具體代碼在后面。
三,滑動(dòng)處理思路
滑動(dòng)都靠底層ScrollView,禁用web和table的滑動(dòng),上面說了底層ScrollView的可滑動(dòng)高度是web和table的總和所以進(jìn)度條是正常的。
然后在滑動(dòng)的同時(shí)不斷調(diào)整contentView的位置,web和table的偏移量,使頁面效果看起來符合預(yù)期。
四,滑動(dòng)處理具體操作,整個(gè)滑動(dòng)可以分成五階段。ps:offsety 底層ScrollView的偏移量
1.offsety<=0,不用過多操作正常滑動(dòng)
2.web內(nèi)部可以滑動(dòng)??刂芻ontentView懸浮,使web在屏幕可視區(qū)域。同時(shí)修改web的偏移量。
3.web滑動(dòng)到頭。保持contentView的位置和web的偏移量,使table滑動(dòng)到屏幕可視區(qū)域
4.table內(nèi)部可以滑動(dòng)??刂芻ontentView懸浮,使table在屏幕可視區(qū)域。同時(shí)修改table的偏移量。
5.table滑動(dòng)到頭。保持contentView的位置和table的偏移量,使頁面滑動(dòng)到底部
四,具體代碼
1.因?yàn)閣eb和table都是隨內(nèi)容變高的,這里選擇通過監(jiān)聽兩者高度變化,同時(shí)刷新各個(gè)控件的高度,對(duì)應(yīng)第二步驟
//添加監(jiān)聽
[self.webView addObserver:self forKeyPath:@"scrollView.contentSize" options:NSKeyValueObservingOptionNew context:nil];
[self.collectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
//刷新各個(gè)控件高度
- (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.具體滑動(dòng)處理代碼
- (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");
}
}
打完收工。