写在前面

首先声明哈,不是广告,我就是用的时候觉得这个功能比较好玩,就想着实现了一下。效果如图:

接下来简单的说一下思路吧~

大体思路

可能我们看到这种功能的实现的时候,首先想着的是我在这个控制器中左右各放一个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 联动效果实现的更多相关文章

  1. 实现外卖选餐时两级 tableView 联动效果

    最近实现了下饿了么中选餐时两级tableView联动效果,先上效果图,大家感受一下: 下面说下具体实现步骤: 首先分解一下,实现这个需求主要是两点,一是点击左边tableView,同时滚动右边tabl ...

  2. iOS 类似外卖 两个tableView联动

    在伯乐在线上看到一个挺好玩的文章,自己也参考文章实现了一下. 效果实现如图所示: 具体实现的内容可以参考原文,参考文章:<iOS 类似美团外卖 app 两个 tableView 联动效果实现&g ...

  3. 美团外卖app可行性分析

    美团外卖app可行性分析 1 引言 1.1编写目的 年轻人追求时尚,快捷,因此外卖行业拥有广阔的消费群体:团购的兴起,也促进了人们的消费欲望,人们继续一个外卖平台,来满足他们的欲望.O2o模式的日渐完 ...

  4. 「美团外卖APP签约快捷支付」流程体验

    §1 添加银行卡 新用户在美团外卖APP订餐支付时,首先要绑定银行卡.如下是“添加银行卡”页,输入卡号后,系统自动调用卡bin库校验卡号的有效性,如果有效会显示发卡行和卡类型(借记卡/贷记卡).  这 ...

  5. 【转】swift实现ios类似微信输入框跟随键盘弹出的效果

    swift实现ios类似微信输入框跟随键盘弹出的效果 为什么要做这个效果 在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会 ...

  6. 仿饿了吗点餐界面两个ListView联动效果

    这篇文章主要介绍了仿饿了点餐界面2个ListView联动效果的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 如图是效果图: 是仿饿了的点餐界面 1.点击左侧的ListView,通过在在适 ...

  7. iOS 类似美团或饿了么评价中的星星评分控件

    1.做的好几个项目都用到了评分控件,可以用来展示评分,也可以用来写评分,图片和间距大小都可以定制,之前就已经简单封装了一个,现在把它分享出来,有需要的拿去用. 2.下面是展示截图:   image.p ...

  8. swift实现ios类似微信输入框跟随键盘弹出的效果

    封面(图文无关) 为什么要做这个效果 在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会跟随键盘一起向下收回,二者完全无缝连 ...

  9. 使用iOSSelect.js实现iOS的select下拉选择日期的联动效果

    引入文件: <link rel="stylesheet" href="/static/css/iosSelect.css"> <script ...

随机推荐

  1. Eclipse中修改Maven Repository

    1. 下载最新的Maven,解压到目录下 Maven下载地址: http://maven.apache.org/download.cgi 2. 修改config/settings.xml文件,在loc ...

  2. php基础知识【函数】(8)xml和变量函数

     一.XML函数 参数类型 data    --string,需要解析的数据集. parser  --resource,一个指向要取得字节索引的 XML 解析器的引用.  1.创建和释放XMl解析器 ...

  3. 缓存淘汰算法---LRU

    1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. ...

  4. python模块之re正则表达式

    41.python的正则表达式      1. python中re模块提供了正则表达式相关操作 字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字      \W大写代表非\w ...

  5. git extrad_addons 部署说明

    注册一个git账号 : 网址:  https://github.com/ 1:安装git   sudo apt-get install git 2:  b把urc扩展占模块pull下来    cd   ...

  6. centos下安装chdmg

    http://www.aboutyun.com/thread-9075-1-1.html  基本参考这个   yum clean all yum update     1.保证selinux关闭  / ...

  7. redis运行状态图形化监控工具 — RedisLive

    在Centos中部署redis运行状态图形化监控工具 — RedisLive   写在前面 前两天看到张善友老师的一篇文章<先定个小目标, 使用C# 开发的千万级应用>,里面给出了一张腾讯 ...

  8. c# appdomain

    http://www.cnblogs.com/Terrylee/archive/2005/11/28/285809.html

  9. java security

    安全性是Java应用程序的非功能性需求的重要组成部分,如同其它的非功能性需求一样,安全性很容易被开发人员所忽略.当然,对于Java EE的开发人员来说,安全性的话题可能没那么陌生,用户认证和授权可能是 ...

  10. javascript summary

    Client Javascript HTML5: http://www.html5rocks.com/en/ Libraray: JQuery, JQuery Mobile, Zepto, MoolT ...