iOS 类似美团外卖 app 两个 tableView 联动效果实现
写在前面
首先声明哈,不是广告,我就是用的时候觉得这个功能比较好玩,就想着实现了一下。效果如图:
接下来简单的说一下思路吧~
大体思路
可能我们看到这种功能的实现的时候,首先想着的是我在这个控制器中左右各放一个tableView,然后进行关联。我是用了另一个思路,具体如下:
我建了两个类LGJCategoryVC用来盛放左边写着第几类的tableView和LGJProductsVC用来盛放右边写在各种产品的tableView。然后将LGJProductsVC作为LGJCategoryVC的childViewController,将LGJProductsVC的viewaddSubView到LGJCategoryVC的view上。
代码实现如下:
- (void)createProductsVC {
_productsVC = [[LGJProductsVC alloc] init];
_productsVC.delegate = self;
[self addChildViewController:_productsVC];
[self.view addSubview:_productsVC.view];
}
这样做有什么好处呢?简单的说就是将tableView分离,各自使用一个congtroller,这样做使每个控制器管理自己的tableView里面的事件,可以更好的分离代码,降低两个tableView之间的耦合度,同时也避免了把两个 tableView放在一个controller里造成一个controller代码的冗余,这样使逻辑更清晰。
接下来说一下我们点击左边tableView的cell的时候怎样使右边的tableView跟着滑动。我在LGJCategoryVC也就是左边tableView的这个代理方法中didSelectRowAtIndexPath做了些操作:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_productsVC) {
[_productsVC scrollToSelectedIndexPath:indexPath];
}
}
其中这个scrollToSelectedIndexPath方法是在_productsVC中声明的。这个方法就是具体调动右边tableView滑动的。
#pragma mark - 一级tableView滚动时 实现当前类tableView的联动
- (void)scrollToSelectedIndexPath:(NSIndexPath *)indexPath {
[self.productsTableView selectRowAtIndexPath:([NSIndexPath indexPathForRow:0 inSection:indexPath.row]) animated:YES scrollPosition:UITableViewScrollPositionTop];
}
我们需要的只是让右边tableView的sectionHeaderView跟随左边的点击cell移动到最上部就可以了,所以在这里我们设置selectRowAtIndexPath:([NSIndexPath indexPathForRow:0 inSection:indexPath.row])
接下来就是当我们滑动右边tableView的时候左边的tableView的cell跟随滑动。这里我们在LGJProductsVC类中声明了一个协议。
@protocol ProductsDelegate <NSObject>
- (void)willDisplayHeaderView:(NSInteger)section;
- (void)didEndDisplayingHeaderView:(NSInteger)section;
@end
同时声明两个变量,这两个变量非常有用。
@property(nonatomic, assign)BOOL isScrollUp;//是否是向上滚动
@property(nonatomic, assign)CGFloat lastOffsetY;//滚动即将结束时scrollView的偏移量
具体作用就在这里了:
#pragma mark - scrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(@"_lastOffsetY : %f,scrollView.contentOffset.y : %f", _lastOffsetY, scrollView.contentOffset.y);
_isScrollUp = _lastOffsetY < scrollView.contentOffset.y;
_lastOffsetY = scrollView.contentOffset.y;
NSLog(@"______lastOffsetY: %f", _lastOffsetY);
}
在这个方法中,_isScrollUp用来判断右边的tableView是否是向上滑,当scrollView滑动时,我们用上次的偏移量和本次的偏移量作对比,如果上次的偏移量小于本次的偏移量说明tableView是向上滑动的。(关于contentOffset我在上篇的《iOS 实现NavigationController的titleView动态缩放效果》链接:http://www.jianshu.com/p/bcf3d692f99d 中有简单介绍)此时,_isScrollUp为YES,反之为NO。我们根据_isScrollUp这个重要的标识来到这儿:UITableViewDelegate的这两个代理方法
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(willDisplayHeaderView:)] != _isScrollUp) {
[self.delegate willDisplayHeaderView:section];
}
}
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(didEndDisplayingHeaderView:)] && _isScrollUp) {
[self.delegate didEndDisplayingHeaderView:section];
}
}
在UITableViewDelegate的这两个代理方法中,第一个方法是当headerView将要显示时调用。第二个方法是当headerView结束显示时调用。在这里我们根据_isScrollUp的BOOL值,当headerView将要显示的时候说明此时_isScrollUp为NO,因为此时是向下滑动的。当headerView结束显示的时候说明此时_isScrollUp为YES,因为此时是向上滑动的。此时我们调用ProductsDelegate代理方法,在LGJCategoryVC类中实现代理方法:
#pragma mark - ProductsDelegate
- (void)willDisplayHeaderView:(NSInteger)section {
[self.categoryTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}
- (void)didEndDisplayingHeaderView:(NSInteger)section {
[self.categoryTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:section + 1 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}
在willDisplayHeaderView这个代理方法中,右边tableView向下滑动,此时headerView即将显示,左边cell选择indexPathForRow:section,在didEndDisplayingHeaderView代理方法中,右边tableView向上滑动,此时headerView结束显示,左边cell选择indexPathForRow:section+1
总结
基本的大体思路就是上面这些,可能老是左边tableView右边tableView的看起来有点儿绕了,具体的还是看代码吧。最后贴上代码链接:
https://github.com/iOSJason/TableViewTwoLevelLinkageDemo.git
希望可以和大家一起交流,一同进步。3Q
iOS 类似美团外卖 app 两个 tableView 联动效果实现的更多相关文章
- 实现外卖选餐时两级 tableView 联动效果
最近实现了下饿了么中选餐时两级tableView联动效果,先上效果图,大家感受一下: 下面说下具体实现步骤: 首先分解一下,实现这个需求主要是两点,一是点击左边tableView,同时滚动右边tabl ...
- iOS 类似外卖 两个tableView联动
在伯乐在线上看到一个挺好玩的文章,自己也参考文章实现了一下. 效果实现如图所示: 具体实现的内容可以参考原文,参考文章:<iOS 类似美团外卖 app 两个 tableView 联动效果实现&g ...
- 美团外卖app可行性分析
美团外卖app可行性分析 1 引言 1.1编写目的 年轻人追求时尚,快捷,因此外卖行业拥有广阔的消费群体:团购的兴起,也促进了人们的消费欲望,人们继续一个外卖平台,来满足他们的欲望.O2o模式的日渐完 ...
- 「美团外卖APP签约快捷支付」流程体验
§1 添加银行卡 新用户在美团外卖APP订餐支付时,首先要绑定银行卡.如下是“添加银行卡”页,输入卡号后,系统自动调用卡bin库校验卡号的有效性,如果有效会显示发卡行和卡类型(借记卡/贷记卡). 这 ...
- 【转】swift实现ios类似微信输入框跟随键盘弹出的效果
swift实现ios类似微信输入框跟随键盘弹出的效果 为什么要做这个效果 在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会 ...
- 仿饿了吗点餐界面两个ListView联动效果
这篇文章主要介绍了仿饿了点餐界面2个ListView联动效果的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 如图是效果图: 是仿饿了的点餐界面 1.点击左侧的ListView,通过在在适 ...
- iOS 类似美团或饿了么评价中的星星评分控件
1.做的好几个项目都用到了评分控件,可以用来展示评分,也可以用来写评分,图片和间距大小都可以定制,之前就已经简单封装了一个,现在把它分享出来,有需要的拿去用. 2.下面是展示截图: image.p ...
- swift实现ios类似微信输入框跟随键盘弹出的效果
封面(图文无关) 为什么要做这个效果 在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会跟随键盘一起向下收回,二者完全无缝连 ...
- 使用iOSSelect.js实现iOS的select下拉选择日期的联动效果
引入文件: <link rel="stylesheet" href="/static/css/iosSelect.css"> <script ...
随机推荐
- HTML5 Canvas画数字时钟
先不说废话,没代码算个蛋. 一些地方注释都写得比较清楚,不过这只是部分,因为只有秒针,但是时针,分针的逻辑都是一致的. 代码中有些坐标不知道为什么较不准,看看就好
- 学习WindowsPhone 2013/12/22
菜鸟一枚,只能边看别人的博客变学习来提升自己,参考博客内容:http://blog.csdn.net/column/details/wp-comming.html?page=3 ,稍微看了一下,写的还 ...
- mysql数据库管理备份运维常用命令
登陆mysql: mysql -u root -p password 远程访问开启((%)表示任何主机连接,可以换固定IP来访问远程连接): GRANT ALL ON *.* TO root@'%' ...
- protocol(协议) 和 delegate(委托)也叫(代理)---辨析
protocol和delegate完全不是一回事. 协议(protocol),(名词)要求.就是使用了这个协议后就要按照这个协议来办事,协议要求实现的方法就一定要实现. 委托(delegate),(动 ...
- 一份React-Native学习指南-感谢分享
自己在学习React-Native过程中整理的一份学习指南,包含 教程.开源app和资源网站等,还在不断更新中.欢迎pull requests! React-Native学习指南 本指南汇集React ...
- iOS 16进制颜色和UIcolor的转换
各种颜色之间的转换,会陆续更新, 实现了 16进制颜色(HEX).RGBA.HSBA.UIColor之间的 相互转换 使用示例(加号方法,类名调用) //UIColor 转 RGB.HSB RGBA ...
- JVM中内存回收深入分析,各种垃圾收集器
JVM启动有两种模式,client和server 一般JVM启动时会根据主机情况分析选择采用那种模式启动 可发现是server模式 JVM中尤其需要关注的就是HEAP堆区 堆区分为新生代和老年代 新生 ...
- [置顶] export命令-linux
export 命令 功能说明: 设置或显示环境变量. 语 法: export [-fnp][变量名称]=[变量设置值] 补充说明: 在shell中执行程序时,shell会提供一组环境变量. expor ...
- VS2010如何生成release文件
点击生成-->配置管理器-->活动解决方案配置下拉菜单中选择release就行了,最后再编译一下就在相应的目录下生成了
- kafka消息监控-KafkaOffsetMonitor
参照site:https://github.com/quantifind/KafkaOffsetMonitor 一.简述 这个应用程序用来实时监控Kafka服务的Consumer以及它们所在的Part ...