文档章节

外卖App双列表联动

杭城小刘
 杭城小刘
发布于 2017/09/24 16:04
字数 820
阅读 11
收藏 0

双列表联动

用过了那么多的外卖App,总结出一个规律,那就是“所有的外卖App都有双列表联动功能”。哈哈哈哈,这是一个玩笑。

这次我也需要开发具有联动效果的双列表。也是首次开发这种类型的UI,记录下步骤与心得

一、关键思路

  • 懒加载左右2个UITableView
  • 根据需要自定义Cell
  • 2个UITableView加载到界面上的时候注意下部剧就好
  • 因为需要联动效果,所有左侧的UITableView一般是大的分类,右边的UITableView一般是大分类小的小分类,所以有了这样的特点
    • 左边的UITableView是只有1个section和n个row
    • 右边的UITableView具有n个section(这里的section 个数恰好是左边UITableView的row数量),且每个section下的row由对应的数据源控制

二、第一版代码

#pragma mark -- UITableViewDelegate
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    if (tableView == self.leftTablview) {
        return 1;
    }
    return self.datas.count;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    if (tableView == self.leftTablview) {
        return self.datas.count;
    }
    QuestionCollectionModel *model = self.datas[section];
    NSArray *questions =model.questions;
    return questions.count;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (tableView == self.leftTablview) {
        return LeftCellHeight;
    }
    return RightCellHeight;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (tableView == self.leftTablview) {
        PregnancyPeriodCell *cell = [tableView dequeueReusableCellWithIdentifier:PregnancyPeriodCellID forIndexPath:indexPath];
        if (self.collectionType == CollectionType_Wrong || self.collectionType == CollectionType_Miss) {
            QuestionCollectionModel *model = self.datas[indexPath.row];
            cell.week = model.tag;
        }

        return cell;
    }
    QuestionCell *cell = [tableView dequeueReusableCellWithIdentifier:QuestionCellID forIndexPath:indexPath];
    QuestionCollectionModel *model = self.datas[indexPath.section];
    NSArray *questions =model.questions;
    QuestionModel *questionModel = questions[indexPath.row];
    cell.model = questionModel;
    return cell;
}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if (tableView == self.leftTablview) {
        NSIndexPath *indexpath = [NSIndexPath indexPathForRow:0 inSection:indexPath.row];
        [self.rightTableview scrollToRowAtIndexPath:indexpath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (scrollView == self.rightTableview) {
        NSIndexPath *indexpath = [self.rightTableview indexPathsForVisibleRows].firstObject;
        NSIndexPath *leftScrollIndexpath = [NSIndexPath indexPathForRow:indexpath.section inSection:0];
        [self.leftTablview selectRowAtIndexPath:leftScrollIndexpath animated:YES scrollPosition:UITableViewScrollPositionMiddle];

    }
}

缺陷:虽然实现了效果,但是有缺陷。点击左侧的UITableView,右侧的UITableViewe滚动到相应的位置,这是没问题的,但是滚动

右边,需要根据右边indexPath.section将选中左侧相应的indexPath。这样左侧选中的时候,又会触发右边滚动的事件,整体看上去不是很流畅。

三、解决方案

观察了下,发现右侧滚动的时候左侧会上下选中,所以也就是只要让右侧滚动的时候,左侧的UITableView单方向选中,不要滚动就好,所以由于UITableView也是UIScrollview,所以在scrollViewDidScroll方法中判断右侧的UITableView是向上还是向下滚动,以此作为判断条件来让左侧的UITableView选中相应的行。

且之前是在scrollview代理方法中让左侧的tableview选中,这样子又会触发左侧tableview的选中事件,从而导致右侧的tablview滚动,造成不严谨的联动逻辑

改进后的方法:

  1. 点击左侧的UITableView,在代理方法didSelectRowAtIndexPath中拿到相应的indexPath.row,计算出右侧UITableView需要滚动的indexPath的位置。
     [self.rightTableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] atScrollPosition:UITableViewScrollPositionTop animated:YES];
    
  2. 在willDisplayCell和didEndDisplayingCell代理方法中选中左侧UITableView相应的行。
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if (tableView == self.rightTableview  && !self.isScrollDown && self.rightTableview.isDragging ) {
        [self.leftTablview selectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
    }
}



-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (tableView == self.rightTableview && self.isScrollDown && self.rightTableview.isDragging) {
        [self.leftTablview selectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.section+1 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];

    }
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
    if (self.leftTablview == tableView)
    {
        [self.rightTableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }else{
        NSLog(@"嗡嗡嗡");
    }
}


#pragma mark - UIScrollViewDelegate

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

    static CGFloat lastOffsetY = 0;

    UITableView *tableView = (UITableView *)scrollView;
    if (self.rightTableview == tableView){
        self.isScrollDown = (lastOffsetY < scrollView.contentOffset.y);
        lastOffsetY = scrollView.contentOffset.y;
    }

}
效果图

效果图

附上Demo:Demo

© 著作权归作者所有

共有 人打赏支持
杭城小刘
粉丝 14
博文 109
码字总数 54955
作品 0
杭州
iOS工程师
WeX5 V3.4 预览版发布,快速开发平台

WeX5v3.4Pre(Windows/Mac) 下载地址: http://pan.baidu.com/s/1jGZoAMy WeX5 V3.4预览版较抢鲜版做了如下更新: 1、新增com.justep.cordova.plugin.touchid 指纹识别插件,只支持iOS; 2、...

muyu
2016/03/22
4.2K
6
智察大数据:2018年1月饿了么、美团外卖对比报告

  2017年外卖行业经历了一系列变革。年初各外卖平台迎来大量融资,在业务快速扩张的同时,也引发一系列食品安全问题,国家监管部门迅速应对,陆续推出多项文件规范外卖市场。阿里巴巴集团加...

智察大数据
03/23
0
0
WeX5 快速开发平台 V3.4 正式版发布

WeX5 V3.4 正式版下载地址 http://pan.baidu.com/s/1jHBUDtc WeX5 V3.4正式版发布说明: 1、新增移动端模板32个:包括首页、数据列表、数据展示、注册、登录、搜索等常用单页面模板和完整应用...

muyu
2016/04/01
5.7K
17
Wex5 3.3版本外卖教程

外卖数据交互 外卖概述 第一讲 搭建页面框架 第二讲 开发菜品列表页 第三讲 开发购物车页 第四讲 开发我的信息页 第五讲 开发订单页 第六讲 细节处理 第七讲 开发后端服务 第八讲 在App中支付...

muyu
2016/01/17
688
0
美团外卖Android平台化的复用实践

美团外卖平台化复用主要是指多端代码复用,正如美团外卖iOS多端复用的推动、支撑与思考文章所述,多端包含有两层意思:其一是相同业务的多入口,指美团外卖业务需要在美团外卖App(下文简称外...

美团技术团队
前天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Qt编写自定义控件属性设计器

以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用...

飞扬青云
35分钟前
1
0
我为什么用GO语言来做区块链?

Go语言现在常常被用来做去中心化系统(decentralised system)。其他类型的公司也都把Go用在产品的核心模块中,并且它在网站开发中也占据了一席之地。 我们在决定做Karachain的时候,考量(b...

HiBlock
40分钟前
1
0
大数据学习脑图以及入门教程!

近些年,大数据的火热可谓是技术人都知道啊,很多人呢,也想学习大数据相关,所以,这里分享几个大数据脑图,希望可以让你清楚明白从哪里入门大数据,知道该学习以及掌握哪些知识点; 大数据...

董黎明
今天
1
0
聊聊redis的监控工具

序 本文主要研究一下redis的监控工具 redis-stat redis-stat是一个比较有名的redis指标可视化的监控工具,采用ruby开发,基于redis的info命令来统计,不影响redis性能。 docker运行 docker r...

go4it
今天
2
0
TypeScript基础入门之高级类型的索引类型(Index types)

转发 TypeScript基础入门之高级类型的索引类型(Index types) 高级类型 索引类型(Index types) 使用索引类型,编译器就能够检查使用了动态属性名的代码。 例如,一个常见的JavaScript模式是从...

durban
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部