這篇文章主要介紹ios中如何使用scrollview嵌套tableview同向滑動(dòng),文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
臨澤ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!
我討論的問題是嵌套同向滑動(dòng),能避免盡量避免。最好用一個(gè)tableview實(shí)現(xiàn)。一個(gè)tableview不夠用了再嵌套,適用復(fù)雜場(chǎng)景。
首先我說下不適用的,免得大家浪費(fèi)時(shí)間。
1.不適用上下拉刷新加載更多的頁(yè)面。
2.不適用點(diǎn)擊cell獲取點(diǎn)擊事件的頁(yè)面,可以加入button點(diǎn)擊獲取事件。
官方文檔說盡量不要進(jìn)行兩個(gè)豎直或兩個(gè)水平方向滑動(dòng)的視圖嵌套。因?yàn)檫@個(gè)時(shí)候機(jī)器不知道用戶要讓哪個(gè)滑動(dòng),但在我們這個(gè)神奇的國(guó)度,項(xiàng)目中經(jīng)常出現(xiàn)這樣的需求,產(chǎn)品經(jīng)理總愛這樣做,andriod那邊是比較容易實(shí)現(xiàn)的,ios這邊十分復(fù)雜,我研究了一天,寫了個(gè)demo,可以勉強(qiáng)實(shí)現(xiàn),我的項(xiàng)目中就有上下拉,因此我就硬嵌套了,用戶滑動(dòng)的時(shí)候不能準(zhǔn)確地按自己的意愿滑動(dòng)scrollview、tableview。就這樣了,這個(gè)沒有解決方案的。
我做到的效果是手點(diǎn)在哪個(gè)視圖上,哪個(gè)視圖就滾動(dòng),當(dāng)小的scroll滾到到自己的臨界值就滾動(dòng)大的scroll,當(dāng)大的也到臨界值就不滾動(dòng)。順便實(shí)現(xiàn)了一個(gè)偽懸浮的secView如果沒有那個(gè)懸浮的就把那個(gè)懸浮高度f(wàn)loatViewHeight置0。剩下的根據(jù)頁(yè)面調(diào)整frame即可通用。
這是效果圖
下面我說一下在沒有以上兩點(diǎn)不適用的頁(yè)面的實(shí)現(xiàn)的思路:
Scrollview在控制器的view上,是一個(gè)大的視圖,tablewview在ScrollView上。根據(jù)拖拽手勢(shì)配合,先判斷首先觸摸點(diǎn)在哪個(gè)view上,再對(duì)哪個(gè)view滑動(dòng)操作。解決手勢(shì)和button點(diǎn)擊沖突。下面看代碼,注釋十分清晰。github有demo,歡迎閱讀: https://github.com/qingyindaoren/ScrollInsetTable.git
核心代碼如下:
#import "ViewController.h" #import "YYGestureRecognizer.h" #import "ScrollTableViewCell.h" #import "MBProgressHUD+Add.h" #define ScreenWidth [UIScreen mainScreen].bounds.size.width #define ScreenHeight [UIScreen mainScreen].bounds.size.height //虛假的懸浮效果 static CGFloat floatViewHeight = 30.0; static CGFloat navHeitht = 64; // 這個(gè)系數(shù)根據(jù)自己喜好設(shè)置大小,=屏幕視圖滑動(dòng)距離/手指滑動(dòng)距離 #define moveScale 2 @interface ViewController ()@property (nonatomic,weak)UIScrollView *scroll; @property (nonatomic, strong) NSArray *titles; @property (nonatomic,weak)UITableView *insetTableView; @property (nonatomic,assign)CGFloat tableY; @property (nonatomic,assign)CGFloat tableStartY; @property (nonatomic,assign)CGFloat scrollY; @property (nonatomic,assign)CGFloat scrollStartY; //tableview 的y值 在scrollview中的位置 @property (nonatomic,assign)CGFloat tableFrameY; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor whiteColor]; self.title = @"ScrollScroll"; // 有導(dǎo)航最上部視圖是scrollview 內(nèi)部空間位置會(huì)下移,設(shè)置這個(gè)屬性后不下移。 if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) { self.automaticallyAdjustsScrollViewInsets = NO; } UIScrollView *scroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0,navHeitht, ScreenWidth, ScreenHeight-navHeitht)]; scroll.backgroundColor = [UIColor colorWithRed:0.4 green:0.3 blue:0.2 alpha:1.0];; [self.view addSubview:scroll]; self.scroll = scroll; //根據(jù)需求設(shè)置tableview的y值 暫寫scroll高的2分之一 self.tableFrameY = self.scroll.frame.size.height/2; UIImageView *headImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, self.tableFrameY-floatViewHeight)]; headImage.image = [UIImage imageNamed:@"scrollHead"]; headImage.contentMode = UIViewContentModeScaleAspectFill; [self.scroll addSubview:headImage]; NSArray *titles = @[@"ICO詳情",@"央行放大招",@"比特幣會(huì)漲",@"神秘中本村"]; self.titles = titles; UISegmentedControl *segment = [[UISegmentedControl alloc] initWithFrame:CGRectMake(5, scroll.bounds.size.height/2-30, self.scroll.bounds.size.width - 10, 30)]; [segment addTarget:self action:@selector(segmentValueChanged:) forControlEvents:UIControlEventValueChanged]; for (NSString *title in _titles) { [segment insertSegmentWithTitle:title atIndex:segment.numberOfSegments animated:false]; } segment.selectedSegmentIndex = 0; [self.scroll addSubview:segment]; UITableView *insetTable = [[UITableView alloc]initWithFrame:CGRectMake(0,self.tableFrameY, self.view.bounds.size.width, ScreenHeight-navHeitht-floatViewHeight)]; insetTable.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0]; insetTable.dataSource = self; insetTable.delegate = self; [self.scroll addSubview:insetTable]; self.insetTableView = insetTable; //github搜索 yykit 或yytext 里面有 yygestureRecognizer這個(gè)類,這個(gè)類需要做一些修改, // 在yygesture中所有觸摸事件方法里 加上super的方法,原文件里沒有,否則響應(yīng)鏈條中斷,scroll或tablew的按鈕點(diǎn)擊事件不執(zhí)行。 //這個(gè)類原文件繼承于UIGestureRecognizer, 改為繼承于UIPanGestureRecognizer 否則點(diǎn)擊事件不執(zhí)行。 //運(yùn)行效果詳見我的demo YYGestureRecognizer *yyges = [YYGestureRecognizer new]; yyges.action = ^(YYGestureRecognizer *gesture, YYGestureRecognizerState state){ if (state != YYGestureRecognizerStateMoved) return ; if (CGRectContainsPoint(self.insetTableView.frame, gesture.startPoint)) { //滑動(dòng)tableview [self tableScrollWithGesture:gesture]; }else{ //滑動(dòng)scrollview [self scrollScrollWithGesture:gesture]; } }; //必須給scroll 加上手勢(shì) 不要給view加,不然滑動(dòng)tablew的時(shí)候會(huì)錯(cuò)誤判斷去滑動(dòng)scroll。 [self.scroll addGestureRecognizer:yyges]; //實(shí)現(xiàn)手勢(shì)代理,解決交互沖突 yyges.delegate = self; scroll.contentSize = CGSizeMake(self.view.bounds.size.width, self.tableFrameY+self.insetTableView.frame.size.height); } //解決手勢(shì)按鈕沖突 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { //如果是 segment或scroll上的其他按鈕,取消手勢(shì) if([NSStringFromClass(touch.view.superclass) isEqualToString:@"UIControl"]){ return NO; } // return YES; } // - (void)segmentValueChanged:(UISegmentedControl *)segment { //scroll 到底部 CGFloat offset = self.scroll.contentSize.height - self.insetTableView.bounds.size.height-floatViewHeight; if (offset > 0) { self.scrollY = offset; [self.scroll setContentOffset:CGPointMake(0, offset) animated:YES]; } //TableView到頂部 self.tableY = 0; [self.insetTableView setContentOffset:CGPointMake(0, self.tableY) animated:YES]; } - (void)tableScrollWithGesture:(YYGestureRecognizer *)gesture{ CGFloat scrolly; if (self.tableStartY != gesture.startPoint.y) { scrolly = -(gesture.currentPoint.y-gesture.startPoint.y) ; }else{ scrolly = -(gesture.currentPoint.y-gesture.lastPoint.y) ; } self.tableStartY = gesture.startPoint.y; self.tableY += scrolly*moveScale; //為了顯示底部超出屏幕的tableview那部分 滑動(dòng)scrollview 此時(shí)tablewview已經(jīng)滑動(dòng)到了底部 if (self.tableY> self.insetTableView.contentSize.height-self.insetTableView.bounds.size.height){ self.scrollY += self.tableY-(self.insetTableView.contentSize.height-self.insetTableView.bounds.size.height); //tablewview滑動(dòng)到底部就不要滑了 self.tableY = self.insetTableView.contentSize.height-self.insetTableView.bounds.size.height; //scrollview 滑動(dòng)到了底部就不要滑動(dòng)了 if (self.scrollY> self.scroll.contentSize.height-self.insetTableView.bounds.size.height-floatViewHeight){ self.scrollY = self.scroll.contentSize.height-self.insetTableView.bounds.size.height-floatViewHeight; //如果scrollview意外的contentsize 小于自己的大小,scrollview就不要滑了 if (self.scrollY<0) { self.scrollY = 0; } } [self.scroll setContentOffset:CGPointMake(0, self.scrollY) animated:YES]; //如果tablewview的cell過少或行高過少致使其contentsize 小于自己的大小,tableview就不要滑了 if (self.tableY<0) { self.tableY = 0; } } //如果滑到了tableview的最上部,停止滑動(dòng)tablewview, 如果此時(shí)scrollview 沒有在最上部就滑動(dòng)scrollview到最上部 if (self.tableY<0){ self.scrollY += self.tableY; //scroll已經(jīng)在最上部了,scroll就不滑了 if (self.scrollY<0) { self.scrollY = 0; } NSLog(@"scroll %lf",self.scrollY); [self.scroll setContentOffset:CGPointMake(0, self.scrollY) animated:YES]; //停止滑動(dòng)tablewview self.tableY = 0; } NSLog(@"table %lf",self.tableY); [self.insetTableView setContentOffset:CGPointMake(0, self.tableY) animated:YES]; } - (void)scrollScrollWithGesture:(YYGestureRecognizer *)gesture{ CGFloat scrolly; if (self.scrollStartY != gesture.startPoint.y) { scrolly = -(gesture.currentPoint.y-gesture.startPoint.y) ; }else{ scrolly = -(gesture.currentPoint.y-gesture.lastPoint.y) ; } self.scrollStartY = gesture.startPoint.y; self.scrollY += scrolly*moveScale; //如果滑到了scroll的底部就不要滑了 if (self.scrollY> self.scroll.contentSize.height-self.insetTableView.bounds.size.height-floatViewHeight){ self.scrollY = self.scroll.contentSize.height-self.insetTableView.bounds.size.height-floatViewHeight; //如果scrollview意外的contentsize 小于自己的大小,scrollview就不要滑了 if (self.scrollY<0) { self.scrollY = 0; } } //如果滑到了scroll頂部就不要滑了 if (self.scrollY<0){ self.scrollY = 0; } NSLog(@"scroll %lf",self.scrollY); [self.scroll setContentOffset:CGPointMake(0, self.scrollY) animated:YES]; } #pragma mark - 展示tableview的代理 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 70; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 10; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ScrollTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"ScrollTableViewCell"]; if (!cell) { [tableView registerNib:[UINib nibWithNibName:@"ScrollTableViewCell" bundle:nil] forCellReuseIdentifier:@"ScrollTableViewCell"]; cell = [tableView dequeueReusableCellWithIdentifier:@"ScrollTableViewCell"]; } cell.backgroundColor = [UIColor clearColor]; cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.Titletext.text = [NSString stringWithFormat:@"\t第%zd行",indexPath.row]; cell.detailText.text = @"滑屏呀滑屏呀劃呀"; cell.detailText.textColor = self.navigationController.navigationBar.tintColor; cell.indexPath = indexPath; cell.selectCellBlock = ^(NSIndexPath *indexPath) { NSString *tip = [NSString stringWithFormat:@"點(diǎn)擊了第%ld組%ld行",indexPath.section,indexPath.row];; [MBProgressHUD showMessage:tip view:nil]; NSLog(@"%@",tip); }; return cell; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 3; } -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UIView *v = [[UIView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, 50)]; v.backgroundColor = [UIColor orangeColor]; UILabel *l = [[UILabel alloc]initWithFrame:v.bounds]; l.text =[NSString stringWithFormat:@"tableview的組頭%ld",section]; l.textColor = [UIColor whiteColor]; l.textAlignment = NSTextAlignmentCenter; [v addSubview:l]; return v; } //組頭高 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 50; } //這個(gè)方法不可用了,除非點(diǎn)擊了cellcontenview之外的區(qū)域 只能同過加按鈕的方式接受點(diǎn)擊事件 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSLog(@"點(diǎn)擊了第%ld行",indexPath.row); }
以上是“ios中如何使用scrollview嵌套tableview同向滑動(dòng)”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!