iOS一些外卖APP中经典的两个TableView滑动效果彩民

2019-09-10 21:30 来源:未知
率先个供给

1.当点击左侧TableViewCell时候,右边TableView会跟随着滑动到相应的section

1.左边UITableViewdidSelected方法

#pragma mark - UITableViewDelegate- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{//_rightVC 右边TableView子控制器对象 if  { // 子控制器封装的方法 [_rightVC leftTableViewToSelectedAtIndexPath:indexPath]; }}

2.右边UITableView装进方法的完结

//点击左边tableViewCell 滚动时 右边tableView一起滚动- leftTableViewToSelectedAtIndexPath:(NSIndexPath *)indexPath{ [self.rightTableView selectRowAtIndexPath:([NSIndexPath indexPathForRow:0 inSection:indexPath.row]) animated:YES scrollPosition:UITableViewScrollPositionTop];}
效果必要(两点):
  • 点击左侧tableVIew的cell,左侧的tableView滑动至内定地方。
  • 滑动侧面tableView的cell,右边包车型地铁tableView滑动至钦定地方。
废话少说,先看功用:

彩民之家论坛9066777 101.gif

文章最后会有demo地址!

先是,从分界面上来看,很确定是多个UITableview左右滑动的功效。而这种滑动的功用基本是左边的tableView何以和侧面的tableView开展关联,并且点击左边tableView以往左边的tableview也得以滑动到相应的section好了,剖析达成之后,大家应该明白了笔者们的2个须要:1.当点击左侧TableViewCell时候,右边TableView会跟随着滑动到相应的section2.当滑动侧面TableView时候,左边TableView会依照左侧UITableViewsection滑动到对应的UITableViewCell位置

实际思路:

好的,体贴来了,得到这几个会集,不就会得到当前显示器上最上端的cell的indexpath了吧,那就顺风的得到今后外地第indexpath.section个分区了。上代码:#pragma mark - UIScrollViewDelegate-scrollViewDidScroll:(UIScrollView *)scrollView{// 监听tableView滑动// 要是前些天滑动的是左臂的tableView,不做任何管理if ((UITableView *)scrollView == self.leftTableView) return;// 滚动左边tableView,设置选中左边包车型大巴tableView某一行。indexPathsForVisibleRows属性再次来到荧屏上可知的cell的indexPath数组,利用那特个性就足以找到近些日子所在的分区[self.leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:self.rightTableView.indexPathsForVisibleRows.firstObject.section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];}[详解]:

第三个要求

2.当滑动侧面TableView时候,左边TableView会依照侧面UITableViewsection滑动到对应的UITableViewCell位置

1.右边UITableView.h文件

@protocol ScrollAtSectionDelegate <NSObject>//制定代理 - willDisplayHeaderView:(NSInteger)section;- didEndDisplayingHeaderView:(NSInteger)section;@end@interface RightClildViewController : UIViewController//代理属性@property(nonatomic, weak) id<ScrollAtSectionDelegate> delegate;@end

2.右边UITableView.m文件

#import "RightClildViewController.h"@interface RightClildViewController ()<UITableViewDelegate, UITableViewDataSource>/** * 结束滚动时的偏移量 */@property(nonatomic, assign)CGFloat endScrollOffset_Y;/** * 是否可以向上滚动 */@property (nonatomic ,assign)BOOL isUpScroll;/** * 右边的tableView */@property (nonatomic ,strong)UITableView *rightTableView;@end- viewDidLoad { [super viewDidLoad]; _isUpScroll = NO; _endScrollOffset_Y = 0; self.view = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width * 0.25, 64, self.view.frame.size.width * 0.75, self.view.frame.size.height-64)]; [self.view addSubview:self.rightTableView];}//在这里只贴出了 核心代码#pragma mark - UIScrollViewDelegate- scrollViewDidScroll:(UIScrollView *)scrollView { _isUpScroll = _endScrollOffset_Y < scrollView.contentOffset.y; _endScrollOffset_Y = scrollView.contentOffset.y; }/** * 这两个方法从字面意思上就可以看出来 是在页眉将要出现和页眉移动屏外 * 会调用的方法 * tableView的isDecelerating属性 * 返回YES 用户没有触摸滚动tableView 但是tableView还是会移动 * 返回NO 反之 */- tableView:(UITableView *)tableView willDisplayHeaderView:view forSection:(NSInteger)section { if (self.delegate && [self.delegate respondsToSelector:@selector(willDisplayHeaderView:)] != _isUpScroll &&_rightTableView.isDecelerating) { [self.delegate willDisplayHeaderView:section]; } }- tableView:(UITableView *)tableView didEndDisplayingHeaderView:view forSection:(NSInteger)section { if (self.delegate && [self.delegate respondsToSelector:@selector(didEndDisplayingHeaderView:)] && _isUpScroll &&_rightTableView.isDecelerating) { [self.delegate didEndDisplayingHeaderView:section]; }}

3.左边UITableView.m文件

#import "JMSlideView.h"#import "RightClildViewController.h"@interface JMSlideView ()<UITableViewDelegate,UITableViewDataSource,ScrollAtSectionDelegate>/** * 该View对应所在的控制器 */@property (nonatomic ,strong)UIViewController *parentVC;/** * 右边 子控制器 */@property (nonatomic ,strong)RightClildViewController *rightVC;/** * 左边 tableView */@property (nonatomic ,strong)UITableView *tableView;/** * 左边tableView 数据源 */@property (nonatomic ,strong)NSMutableArray *dataArray;/** * 右边tableView 数据源 */@property (nonatomic ,strong)NSMutableArray *rightArray;@end@implementation JMSlideViewstatic NSString *const leftIdentifier = @"leftIdentifier";- (instancetype)initWithFrame:frame leftDataArray:(NSMutableArray *)leftDataArray rightDataArray:(NSMutableArray *)rightDataArray{ self = [super initWithFrame:frame]; if  { self.dataArray = leftDataArray; self.rightArray = rightDataArray; [self addChildViewController]; [self addSubview:self.tableView]; } return self;}//添加子视图控制器- addChildViewController{ self.rightVC = [[RightClildViewController alloc]init]; [self.parentVC addChildViewController:_rightVC]; self.rightVC.headerArray = self.dataArray; self.rightVC.rightArray = self.rightArray; self.rightVC.delegate = self; [self addSubview:_rightVC.view];}#pragma mark - UITableViewDataSource- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataArray.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:leftIdentifier]; cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row]; cell.textLabel.font = [UIFont systemFontOfSize:13]; return cell;}#pragma mark - UITableViewDelegate- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if  { [_rightVC leftTableViewToSelectedAtIndexPath:indexPath]; }}#pragma mark - ScrollAtSectionDelegate- willDisplayHeaderView:(NSInteger)section { [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];}- didEndDisplayingHeaderView:(NSInteger)section { [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:section   1 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];}

#import "ViewController.h"#import "JMSlideView.h"@interface ViewController (){ NSMutableArray *leftDataArray; NSMutableArray *rightDataArray;}@property (nonatomic ,strong)JMSlideView *slideView;@end@implementation ViewController- viewDidLoad { [super viewDidLoad]; leftDataArray = [NSMutableArray arrayWithObjects:@"热销菜品",@"精选组合",@"粥类",@"东北小町米",@"特色佳肴",@"商务套餐",@"开胃冷菜",@"热菜大荤",@"汤类",@"酒水饮料", nil]; rightDataArray = [NSMutableArray arrayWithObjects:@"米饭",@"小炒花菜",@"黑木耳炒山药",@"红烧鸡腿",@"农家小炒肉",@"板栗烧鸡", nil]; [self.view addSubview:self.slideView]; }- (JMSlideView *)slideView{ if (!_slideView) { _slideView = [[JMSlideView alloc]initWithFrame:self.view.bounds leftDataArray:leftDataArray rightDataArray:rightDataArray]; } return _slideView;}

这种看似的滑动作效果果在局地外送食品应用程式中平时探望到。要兑现这种滑动作效果果其实并简单,首要能把思路捋清楚就能够有另一番收货。比如tableView那么些不常用的代理方法及品质,即使可以多询问下,运用到骨子里的等级次序中就能够有意料之外的功用。

世家加油,共同学习!!!

本文demo地址

pragma mark - UIScrollViewDelegate

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

// 监听tableView滑动

// 如若今日滑动的是左臂的tableView,不做别的处理

if ((UITableView *)scrollView == self.leftTableView) return;

// 滚动右侧tableView,设置选中侧边的tableView某一行。

indexPathsForVisibleRows属性重返显示屏上可知的cell的index帕特h数组,

选择那么些天性就足以找到近些日子所在的分区

[self.leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:self.rightTableView.indexPathsForVisibleRows.firstObject.section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];

}

[详解]:

  • 第一监听scrollView的拖动,本demo不管理侧面tableView的轮转,所以

    if ((UITableView *)scrollView == self.leftTableView) return;

  • 下一句代码的意思是,获得前段时间显示屏上可见cell的首先行cell所在的分区,然后让右侧包车型地铁tableView选中第0分区(它独有二个分区)的这一行就OK了。

    self.rightTableView.indexPathsForVisibleRows.firstObject.section

    demo地址:https://github.com/RenZhengYang/ZYLinkageTableView


--------------------------补充-------------------------------

1.点击左侧tableView的时候会有黑影效果

  • 点击左边的tableView,右侧的tableView是从当前职务动画滚动到对应岗位的,既然有滚动,就能够调

    • (void)scrollViewDidScroll:(UIScrollView *)scrollView

    以此代理方法,说白了正是拖动了右边tableView,拖动左侧的历程中会时断时续选中左边。

假如不想要那么些效应,有三个艺术,叁个是平昔把

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

中的动画滚动的性质animated值改成NO

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

// 如若点击的是侧边的tableView,不做别的管理

if (tableView == self.rightTableView) return;

// 点击右侧的tableView,设置选中侧面的tableView某一行。

侧边的tableView的每一行对应左侧tableView的各样分区

[self.rightTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] animated:NO scrollPosition:UITableViewScrollPositionTop];

}

与此相类似做左侧的tableView就是无动画滚动了,也就不会再调scrollViewDidScroll:方法。

不过若是还想左边tableViewyou滚动作效果应,另一种缓和格局是把

  • (void)scrollViewDidScroll:(UIScrollView *)scrollView

格局换来

  • (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

那几个代理方法措施就行了。有的分界面类似正是这么做的,可是有bug(估量饿了么没测出来),那一个艺术的声明为

// called when scroll view grinds to a halt 当滚动视图半途而返--有道翻译如是说

其一措施调用与否在于你的指头是不是在动画结束以前离开了显示屏,假设在动画停止此前手指离开显示器,此方法调用没什么问题。but,固然动画已经甘休,再把手指拿开,那个办法是不会调的。

减轻那几个bug的关键在于,让手指离开的时候手动调三次这么些代理方法,那怎么技术领略手指什么日期离开呢?scrollView给我们了另二个代理方法:

  • (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset

以此艺术在甘休拖拽的时候调,正好化解了笔者们的难点:

  • (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{

// 推拽就要甘休的时候手动调一下这么些办法

[self scrollViewDidEndDecelerating:scrollView];

}


1.// 暗中同意选项右侧tableView的第一行

[_leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];

必须在tableView数据加载完毕后,才会调用。否则会报错。
  • 点击左侧的tableView,侧边的tableView是从当前任务动画滚动到对应岗位的,既然有滚动,就能够调- scrollViewDidScroll:(UIScrollView *)scrollView这几个代理方法,说白了便是拖动了侧边tableView,拖动左侧的进程中会陆陆续续选中左侧。

让大家一起学习一下tableView联合浮动,作者那也是从简书上看来的一篇小说,来亲自落实一下。学习小说地址:http://www.jianshu.com/p/dfb73aa08602

--------------------------补充-------------------------------

先上图:

  • 学习小记:1.// 私下认可选项侧面tableView的首先行[_leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];必需在tableView数据加载达成后,才会调用。不然会报错。
  • 贯彻点击侧面tableView同一时候滚动侧边tableView,只需求贯彻tableView的代办方法。

    • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

    接下来在代理方法里边获得右侧的tableView,实现让其滚动到第index帕特h.row分区,第0行就能够,代码如下:

    • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    // 倘使点击的是侧边的tableView,不做其余管理

    if (tableView == self.rightTableView) return;

    // 点击侧边包车型客车tableView,设置选中侧边的tableView某一行。

    侧边包车型大巴tableView的每一行对应左侧tableView的逐个组第0行

    [self.rightTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] animated:YES scrollPosition:UITableViewScrollPositionTop];

    }

    大家这里不管理侧边tableView的点击事件,所以

    if (tableView == self.rightTableView) return;

    接下去,拖动左侧的tableView,来找到侧面tableView对应的某一行。

    咱俩要动态选中侧边包车型客车tableView,就须求拿到左手tableView现在滚动到了老大组。UITableView有多个代理方法:

    // 二个头标题就要呈现的时候调用

    • (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section

    // 二个头标题将要消失的时候掉用

    • (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section

    动用那八个主意就可以获得当前所在哪些组达成这些功用了。

本篇小说,与读书笔者小说同样,只然则排版,被小编改了,demo中的写法,被自个儿改了。整理一下,学习备用。若有侵犯版权,请及时沟通,小编会做改换。如有欠缺,或有好的主见,请即时建议。互相交换学习,应接点星,慰勉!!!

好的,着重来了,获得那几个集合,不就能够得到日前荧屏上顶上部分的cell的indexpath了呢,那就高枕无忧的得到将来随处第indexpath.section个分区了。

彩民之家论坛9066777 21212.gif

[图形上传失利...(image-e5c7d1-1513741413430)]

以此办法调用与否在于你的指尖是不是在动画甘休从前离开了荧屏,假若在动画甘休在此以前手指离开显示器,此办法调用没什么难题。but,假若动画已经截至,再把手指拿开,这么些格局是不会调的。

再有三个更简便易行的措施,在tableView中,是不经常用的,叫做,indexPathsForVisibleRows官方文书档案解释是:

先上图:

The value of this property is an array of NSIndexPath objects each representing a row index and section index that together identify a visible row in the table view. If no rows are visible, the value is nil.

大致意思是:重临二个荧屏上可见的cell的indexPath会集

作用要求:
  • 点击左侧tableVIew的cell,左侧的tableView滑动至钦命地方。

  • 滑动右侧tableView的cell,左边的tableView滑动至钦定地点。

// called when scroll view grinds to a halt 当滚动视图因噎废食--有道翻译如是说

上代码:

1.点击左边tableView的时候会有阴影效果

消除这几个bug的关键在于,让手指离开的时候手动调一回这么些代理方法,那怎么本领精晓手指曾几何时离开呢?scrollView给我们了另叁个代理方法:- scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:velocity targetContentOffset:(inout CGPoint *)targetContentOffset这么些办法在停止拖拽的时候调,正好化解了大家的标题:- scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:velocity targetContentOffset:(inout CGPoint *)targetContentOffset{// 推拽将在停止的时候手动调一下以此格局[self scrollViewDidEndDecelerating:scrollView];}

  • 第一监听scrollView的拖动,本demo不管理左侧tableView的轮转,所以if ((UITableView *)scrollView == self.leftTableView) return;
  • 下一句代码的情趣是,得到目前荧屏上可知cell的第一行cell所在的分区,然后让右侧的tableView选中第0分区的这一行就OK了。self.rightTableView.indexPathsForVisibleRows.firstObject.sectiondemo地址:

The value of this property is an array of NSIndexPath objects each representing a row index and section index that together identify a visible row in the table view. If no rows are visible, the value is nil.大致意思是:再次回到三个显示器上可知的cell的indexPath集结

让咱们一同学习一下tableView联合浮动,小编那也是从简书上看来的一篇文章,来亲自落实一下。学习文章地址:

  • 得以实现点击侧边tableView同一时间滚动左边tableView,只供给贯彻tableView的代理方法。- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;然后在代理方法里边获得右侧的tableView,完毕让其滚动到第indexPath.row分区,第0行就可以,代码如下:- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{// 倘诺点击的是右侧的tableView,不做其余管理if (tableView == self.rightTableView) return;// 点击侧边的tableView,设置选中右侧的tableView某一行。左侧的tableView的每一行对应右侧tableView的每种组第0行[self.rightTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] animated:YES scrollPosition:UITableViewScrollPositionTop];}我们那边不处理左侧tableView的点击事件,所以if (tableView == self.rightTableView) return;接下去,拖动左边的tableView,来找到侧边tableView对应的某一行。我们要动态选中侧边包车型大巴tableView,就供给得到左手tableView今后滚动到了极其组。UITableView有七个代理方法:// 一个头标题将要突显的时候调用- tableView:(UITableView *)tableView willDisplayHeaderView:view forSection:(NSInteger)section// 三个头标题将要消失的时候掉用- tableView:(UITableView *)tableView didEndDisplayingHeaderView:view forSection:(NSInteger)section选拔这四个办法就能够获得这几天所在哪个组完毕那一个效果了。
切实思路:

还应该有二个更轻松的方法,在tableView中,是有的时候用的,叫做,indexPathsForVisibleRows官方文档解释是:

若果不想要那一个功效,有八个章程,八个是一向把- tableView:(UITableView )tableView didSelectRowAtIndexPath:(NSIndexPath)index帕特h中的动画滚动的属性*animated值改成NO*- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{// 要是点击的是侧面的tableView,不做别的管理if (tableView == self.rightTableView) return;// 点击右侧包车型大巴tableView,设置选中侧面的tableView某一行。左边的tableView的每一行对应侧面tableView的种种分区[self.rightTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] animated:NO scrollPosition:UITableViewScrollPositionTop];}那样做侧边的tableView正是无动画滚动了,也就不会再调scrollViewDidScroll:方法。然而如若还想右侧tableViewyou滚动效应,另一种缓慢解决办法是把- scrollViewDidScroll:(UIScrollView *)scrollView方法换到- scrollViewDidEndDecelerating:(UIScrollView *)scrollView那么些代理方法措施就行了。有的分界面类似就是这么做的,可是有bug(预计饿了么没测出来),那一个办法的表明为

版权声明:本文由彩民之家高手论坛发布于编程技术,转载请注明出处:iOS一些外卖APP中经典的两个TableView滑动效果彩民