iOS中UIScrollView嵌套UITableView的實(shí)踐教程
前言
最近因?yàn)楣ぷ黜?xiàng)目中需要用到UIScrollView嵌套UItableView嵌套交互問(wèn)題,順便網(wǎng)上搜了下的demo,發(fā)現(xiàn)實(shí)現(xiàn)的效果并不是很理想,滑動(dòng)偶爾會(huì)有延遲現(xiàn)象,所以自己想了個(gè)辦法,順便把自己實(shí)現(xiàn)寫了個(gè)demo分享出來(lái),一起來(lái)看看吧。
實(shí)現(xiàn)過(guò)程
最底部放置的為一個(gè)UIScrollView,設(shè)置ScrollView的contentSize屬性,使可以發(fā)生橫向滾動(dòng),同時(shí)隱藏橫向滾動(dòng)條,設(shè)置代理為當(dāng)前控制器本身。然后,在最底部的UIScrollView上放置2個(gè)UITableView,因?yàn)橹挥?個(gè)所以沒(méi)有考慮重用問(wèn)題,如果數(shù)量大于3個(gè)建議寫下UIScrollView子視圖的重用。最后在最上面覆蓋一個(gè)topView,使得它可以和tableView發(fā)生縱向滾動(dòng),為了實(shí)現(xiàn)最上面的topView可以隨著tableView發(fā)生一起滾動(dòng),需要在tableView的scrollViewDidScroll代理方法中獲取tableview的contentOffset偏移量,隨便改變topView的frame。
當(dāng)手勢(shì)點(diǎn)開(kāi)始落在從topView上時(shí)候,在controller的loadView方法中設(shè)置自定義view,通過(guò)在自定義view中重載hittest方法,判斷是否需要讓tableView進(jìn)行交互。此時(shí)需要注意的是因?yàn)橛凶远x的左右選擇segmentControl,這么設(shè)置的時(shí)候segmentController是不會(huì)相應(yīng)點(diǎn)擊方法的。為了讓segmentController可以實(shí)現(xiàn)隨著tableView滾動(dòng)并且可以相應(yīng)單擊事件,我在在controller的view上添加了單擊手勢(shì),判定是否點(diǎn)擊在了自定義的segmentControll上(因?yàn)閠ableView本身不會(huì)相應(yīng)- (void)touchesBegan:(NSSet<UITouch *> )touches withEvent:(UIEvent )event
事件,所以也可以自定義一個(gè)tableVuew,重載touchBegin 等方法,然后把tableView繼承自這個(gè)tableView, 這樣就可以相應(yīng)相應(yīng)的touchbegin等方法了), 好了,下面直接上代碼
controller中代碼如下:
#pragma mark - 底部的scrollViuew的代理方法scrollViewDidScroll - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat placeholderOffset = 0; if (self.topView.getSelectedItemIndex == 0) { if (self.firstTableView.contentOffset.y > self.topView.height - kItemheight) { placeholderOffset = self.topView.height - kItemheight; } else { placeholderOffset = self.firstTableView.contentOffset.y; } [self.secondTableView setContentOffset:CGPointMake(0, placeholderOffset) animated:NO]; } else { if (self.secondTableView.contentOffset.y > self.topView.height - kItemheight) { placeholderOffset = self.topView.height - kItemheight; } else { placeholderOffset = self.secondTableView.contentOffset.y; } [self.firstTableView setContentOffset:CGPointMake(0, placeholderOffset) animated:NO]; } }
#pragma mark - 底部的scrollViuew的代理方法scrollViewDidEndDecelerating - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { NSInteger index = ceilf(scrollView.contentOffset.x / kScreen_Width); self.topView.selectedItemIndex = index; }
controller中view的代碼如下
#pragma mark - 重載系統(tǒng)的hitTest方法 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { ViewController *currentVC = (ViewController *)self.nextResponder; currentVC.printPoint = point; if ([self.topView pointInside:point withEvent:event]) { self.scrollView.scrollEnabled = NO; if (self.scrollView.contentOffset.x < kScreen_Width *0.5) { return self.firstTableView; } else { return self.secondTableView; } } else { self.scrollView.scrollEnabled = YES; return [super hitTest:point withEvent:event]; } }
#pragma mark - 添加手勢(shì)的相應(yīng)方法 - (void)tapGestureAction:(UITapGestureRecognizer *)gesture { CGPoint point = [gesture locationInView:self.topView]; if (CGRectContainsPoint(self.topView.leftBtnFrame, point)) { if (self.scrollView.contentOffset.x > 0.5 * kScreen_Width) { [self.scrollView setContentOffset:CGPointMake(0, 0) animated:NO]; self.topView.selectedItemIndex = 0; } } else if (CGRectContainsPoint(self.topView.rightBtnFrame, point)) { if (self.scrollView.contentOffset.x < 0.5 * kScreen_Width) { [self.scrollView setContentOffset:CGPointMake(kScreen_Width, 0) animated:NO]; self.topView.selectedItemIndex = 1; } } }
#pragma mark - firstTableView的代理方法scrollViewDidScroll - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat placeHolderHeight = self.topView.height - self.topView.itemHeight; CGFloat offsetY = scrollView.contentOffset.y; if (offsetY >= 0 && offsetY <= placeHolderHeight) { self.topView.y = -offsetY; } else if (offsetY > placeHolderHeight) { self.topView.y = - placeHolderHeight; } else if (offsetY <0) { self.topView.y = - offsetY; } }
#pragma mark - secondTableView的代理方法scrollViewDidScroll - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat placeHolderHeight = self.topView.height - self.topView.itemHeight; CGFloat offsetY = scrollView.contentOffset.y; if (offsetY >= 0 && offsetY <= placeHolderHeight) { self.topView.y = -offsetY; } else if (offsetY > placeHolderHeight) { self.topView.y = - placeHolderHeight; } else if (offsetY <0) { self.topView.y = - offsetY; } }
完整項(xiàng)目下載地址如下:https://github.com/maxzhang123/nestScrollView 或者本地下載地址:http://xiazai.jb51.net/201705/yuanma/nestScrollView(jb51.net).rar
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋
這篇文章主要介紹了IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋的相關(guān)資料,需要的朋友可以參考下2016-12-12IOS開(kāi)發(fā)壓縮后圖片模糊問(wèn)題解決
這篇文章主要為大家介紹了IOS開(kāi)發(fā)壓縮后圖片模糊問(wèn)題解決實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07swift3.0網(wǎng)絡(luò)圖片緩存原理簡(jiǎn)析
這篇文章主要為大家簡(jiǎn)析了swift3.0網(wǎng)絡(luò)圖片緩存原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09iOS 禁止按鈕在一定時(shí)間內(nèi)連續(xù)點(diǎn)擊
本文主要介紹了iOS中禁止按鈕在一定時(shí)間內(nèi)連續(xù)點(diǎn)擊的方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02