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)開始落在從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-12
swift3.0網(wǎng)絡(luò)圖片緩存原理簡(jiǎn)析
這篇文章主要為大家簡(jiǎn)析了swift3.0網(wǎng)絡(luò)圖片緩存原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
iOS 禁止按鈕在一定時(shí)間內(nèi)連續(xù)點(diǎn)擊
本文主要介紹了iOS中禁止按鈕在一定時(shí)間內(nèi)連續(xù)點(diǎn)擊的方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02

