iOS 網(wǎng)頁和原生列表混合布局開發(fā)(文章+評(píng)論)

我們總會(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)視圖連在一起的。

整體結(jié)構(gòu)如圖
webAndtable.png

一,視圖介紹

黃色的是底層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");
    }
}

打完收工。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容