登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

两个TableView之间的联动,TableView与CollectionView之间的联动

[复制链接]
来自: LeeJay_Carson 分类: iOS精品源码 上传时间: 2016-8-23 15:43:42
Tag:菜单 购物车 chart 列表 CollectionView

项目介绍:

【联动】:两个TableView之间的联动,TableView与CollectionView之间的联动

新增

用户点击了左侧tableView中靠下的cell时,选中的cell会自动向上滚动。

前言

现在市面上有很多app都有联动功能,有的是两个TableView之间的联动,比如美团外卖,百度外卖,饿了么等等。有的是TableView与CollectionView之间的联动,比如礼物说等等。

本文仿造了美团外卖和礼物说,分别实现了两个TableView之间和TablView与CollectionView之间的联动效果,效果图看下面的gif图。

先附上gif图的demo下载链接,【GitHub】【Code4App】【OSChina】
配合demo一起看文章,效果会更佳。

Usage

正文

一、TableView与TableView之间的联动

下面来说下实现两个TableView之间联动的主要思路:

先解析数据装入模型,objectWithDictionary:是将字典转化为模型,这个工具是我用runtime写的,一行代码解析数据,具体使用方法可以参考我简书上另一篇文章【Objective-C中的Runtime】

NSString *path = [[NSBundle mainBundle] pathForResource:@"meituan" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSArray *foods = dict[@"data"][@"food_spu_tags"];

for (NSDictionary *dict in foods)
{
    CategoryModel *model = [CategoryModel objectWithDictionary:dict];
    [self.categoryData addObject:model];

    NSMutableArray *datas = [NSMutableArray array];
    for (FoodModel *f_model in model.spus)
    {
        [datas addObject:f_model];
    }
    [self.foodData addObject:datas];
}

定义两个TableView:LeftTableView和RightTableView。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (_leftTableView == tableView)
    {
        LeftTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Left forIndexPath:indexPath];
        FoodModel *model = self.categoryData[indexPath.row];
        cell.name.text = model.name;
        return cell;
    }
    else
    {
        RightTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Right forIndexPath:indexPath];
        FoodModel *model = self.productData[indexPath.section][indexPath.row];
        cell.model = model;
        return cell;
    }
}

先将左边的TableView关联右边的TableView:点击左边的TableViewCell,右边的TableView跳到相应的分区列表头部。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
    if (_leftTableView == tableView)
    {
        _selectIndex = indexPath.row;
        [_rightTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:_selectIndex] atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
}

再将右边的TableView关联左边的TableView:标记一下RightTableView的滚动方向,然后分别在TableView分区标题即将展示和展示结束的代理函数里面处理逻辑。

  • 1.在TableView分区标题即将展示里面,判断当前的tableView是RightTableView,RightTableView滑动的方向向上,RightTableView是用户拖拽而产生滚动的(主要判断RightTableView是用户拖拽的,还是点击LeftTableView滚动的),如果三者都成立,那么LeftTableView的选中行就是RightTableView的当前section。

  • 2.在TableView分区标题展示结束里面,判断当前的tableView是RightTableView,滑动的方向向下,RightTableView是用户拖拽而产生滚动的,如果三者都成立,那么LeftTableView的选中行就是RightTableView的当前section-1。

// 标记一下RightTableView的滚动方向,是向上还是向下
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    static CGFloat lastOffsetY = 0;

    UITableView *tableView = (UITableView *) scrollView;
    if (_rightTableView == tableView)
    {
        _isScrollDown = lastOffsetY < scrollView.contentOffset.y;
        lastOffsetY = scrollView.contentOffset.y;
    }
}

// TableView分区标题即将展示
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(nonnull UIView *)view forSection:(NSInteger)section
{
    // 当前的tableView是RightTableView,RightTableView滚动的方向向上,RightTableView是用户拖拽而产生滚动的((主要判断RightTableView用户拖拽而滚动的,还是点击LeftTableView而滚动的)
    if ((_rightTableView == tableView) && !_isScrollDown && _rightTableView.dragging)
    {
        [self selectRowAtIndexPath:section];
    }
}

// TableView分区标题展示结束
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section
{
    // 当前的tableView是RightTableView,RightTableView滚动的方向向下,RightTableView是用户拖拽而产生滚动的(主要判断RightTableView用户拖拽而滚动的,还是点击LeftTableView而滚动的)
    if ((_rightTableView == tableView) && _isScrollDown && _rightTableView.dragging)
    {
        [self selectRowAtIndexPath:section + 1];
    }
}

// 当拖动右边TableView的时候,处理左边TableView
- (void)selectRowAtIndexPath:(NSInteger)index
{
    [_leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
}

这样就实现了两个TableView之间的联动,是不是很简单。

二、TableView与CollectionView之间的联动

TableView与CollectionView之间的联动与两个TableView之间的联动逻辑类似。

下面说下实现TableView与CollectionView之间的联动的主要思路:

还是一样,先解析数据装入模型。

NSString *path = [[NSBundle mainBundle] pathForResource:@"liwushuo" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSArray *categories = dict[@"data"][@"categories"];

for (NSDictionary *dict in categories)
{
    CollectionCategoryModel *model = [CollectionCategoryModel objectWithDictionary:dict];
    [self.dataSource addObject:model];

    NSMutableArray *datas = [NSMutableArray array];
    for (SubCategoryModel *sModel in model.subcategories)
    {
        [datas addObject:sModel];
    }
    [self.collectionDatas addObject:datas];
}

定义一个TableView,一个CollectionView。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    LeftTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Left forIndexPath:indexPath];
    CollectionCategoryModel *model = self.dataSource[indexPath.row];
    cell.name.text = model.name;
    return cell;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier_CollectionView forIndexPath:indexPath];
    SubCategoryModel *model = self.collectionDatas[indexPath.section][indexPath.row];
    cell.model = model;
    return cell;
}

先将TableView关联CollectionView,点击TableViewCell,右边的CollectionView跳到相应的分区列表头部。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    _selectIndex = indexPath.row;
    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:_selectIndex] atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
}

再将CollectionView关联TableView,标记一下RightTableView的滚动方向,然后分别在CollectionView分区标题即将展示和展示结束的代理函数里面处理逻辑。

  • 1.在CollectionView分区标题即将展示里面,判断 当前CollectionView滚动的方向向上,CollectionView是用户拖拽而产生滚动的(主要是判断CollectionView是用户拖拽而滚动的,还是点击TableView而滚动的),如果二者都成立,那么TableView的选中行就是CollectionView的当前section。

  • 2.在CollectionView分区标题展示结束里面,判断当前CollectionView滚动的方向向下,CollectionView是用户拖拽而产生滚动的,如果二者都成立,那么TableView的选中行就是CollectionView的当前section-1。

// 标记一下CollectionView的滚动方向,是向上还是向下
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    static float lastOffsetY = 0;

    if (self.collectionView == scrollView)
    {
        _isScrollDown = lastOffsetY < scrollView.contentOffset.y;
        lastOffsetY = scrollView.contentOffset.y;
    }
}

// CollectionView分区标题即将展示
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
{
    // 当前CollectionView滚动的方向向上,CollectionView是用户拖拽而产生滚动的(主要是判断CollectionView是用户拖拽而滚动的,还是点击TableView而滚动的)
    if (!_isScrollDown && collectionView.dragging)
    {
        [self selectRowAtIndexPath:indexPath.section];
    }
}

// CollectionView分区标题展示结束
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(nonnull UICollectionReusableView *)view forElementOfKind:(nonnull NSString *)elementKind atIndexPath:(nonnull NSIndexPath *)indexPath
{
    // 当前CollectionView滚动的方向向下,CollectionView是用户拖拽而产生滚动的(主要是判断CollectionView是用户拖拽而滚动的,还是点击TableView而滚动的)
    if (_isScrollDown && collectionView.dragging)
    {
        [self selectRowAtIndexPath:indexPath.section + 1];
    }
}

// 当拖动CollectionView的时候,处理TableView
- (void)selectRowAtIndexPath:(NSInteger)index
{
    [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}

TableView与CollectionView之间的联动就这么实现了,是不是也很简单。

最后

由于笔者水平有限,文中如果有错误的地方,或者有更好的方法,还望大神指正。

附上本文的所有demo下载链接,【GitHub】【Code4App】
配合demo一起看文章,效果会更佳。

如果你看完后觉得对你有所帮助,还望在GitHub上点个star。赠人玫瑰,手有余香。 https://github.com/leejayID/Linkage

MADE BY CODE4APP

相关源码推荐:

我来说两句
*滑动验证:
所有评论(694)
zhushouzhi1993 2016-8-23 15:54:04
精华内容,楼主V5!
回复
code4app热心网友 2016-8-23 15:54:57
楼主威武啊,Code4App有你更给力!
回复
code4app热心网友 2016-8-23 15:56:34
淡定,淡定,淡定……
回复
code4app热心网友 2016-8-23 15:58:56
我只是路过打酱油的。
回复
code4app热心网友 2016-8-23 16:08:19
淡定,淡定,淡定……
回复
张旭123 2016-8-23 16:08:39
楼主威武啊,Code4App有你更给力!
回复
code4app热心网友 2016-8-23 16:09:08
强烈支持楼主ing……
回复
18277581700 2016-8-23 16:11:08
感谢分享,Code4App有你更精彩:)
回复
code4app热心网友 2016-8-23 16:11:36
淡定,淡定,淡定……
回复
提取码:  下载次数:586 状态:已购或VIP 售价:0(原价:10)金钱 下载权限:初级码农 
5353 5 586
联系我们
首页/微信公众账号投稿

帖子代码编辑/版权问题

QQ:435399051,742864542

如何获得代码达人称号?

代码贡献英雄榜
用户名 下载数
通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

快速回复 返回顶部 返回列表