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)寫(xiě)了個(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è)建議寫(xiě)下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應(yīng)用開(kāi)發(fā)中對(duì)設(shè)計(jì)模式中的抽象工廠模式的實(shí)現(xiàn)
這篇文章主要介紹了解析iOS應(yīng)用開(kāi)發(fā)中對(duì)設(shè)計(jì)模式中的抽象工廠模式的實(shí)現(xiàn),示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-03-03
詳解IOS11新特性之larget title的實(shí)現(xiàn)
本篇文章主要介紹了詳解IOS11新特性之larget title的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
iOS 通過(guò)collectionView實(shí)現(xiàn)照片刪除功能
這篇文章主要介紹了iOS 通過(guò)collectionView實(shí)現(xiàn)照片刪除功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11
iOS實(shí)現(xiàn)簡(jiǎn)單的二級(jí)菜單效果
這篇文章給大家主要介紹的是利用iOS如何實(shí)現(xiàn)簡(jiǎn)單的菜單效果,文中給出了詳細(xì)的示例代碼,而且實(shí)現(xiàn)的比較簡(jiǎn)單,適合新人學(xué)習(xí)使用。感興趣的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-10-10
iOS表視圖之下拉刷新控件功能的實(shí)現(xiàn)方法
下拉刷新是重新刷新表視圖或列表,以便重新加載數(shù)據(jù),這種模式廣泛用于移動(dòng)平臺(tái),相信大家對(duì)于此也是非常熟悉的,那么iOS是如何做到的下拉刷新呢?下面小編給大家分享iOS表視圖之下拉刷新控件的實(shí)現(xiàn)方法,一起看看吧2017-01-01
詳解iOS中多線程app開(kāi)發(fā)的GCD隊(duì)列的使用
這篇文章主要介紹了詳解iOS中多線程app開(kāi)發(fā)的GCD隊(duì)列的使用,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-12-12
iOS中解決Xcode9的Log日志無(wú)法輸出中文的問(wèn)題小結(jié)
這篇文章主要介紹了iOS中解決Xcode9的Log日志無(wú)法輸出中文的問(wèn)題小結(jié),需要的朋友可以參考下2017-11-11

