美文网首页
UITableView的联动

UITableView的联动

作者: yyggzc521 | 来源:发表于2018-12-05 15:16 被阅读0次

两个tableView的联动梳理清晰了逻辑之后,实现起来其实很简单。


tableView的联动
  1. 设置正确的数据结构
左侧:@[@"",@"",....] 右侧:@[@[@"",@""],@[@"",@""].....] 数据结构
    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];
      #左侧-------tableView的数据源
        [self.categoryData addObject:model];
        
        NSMutableArray *datas = [NSMutableArray array];
        for (FoodModel *f_model in model.spus)  {
            [datas addObject:f_model];
        }
       #右侧-------tableView的数据源
        [self.foodData addObject:datas];
    }
    
    [self.view addSubview:self.leftTableView];
    [self.view addSubview:self.rightTableView];
    
    [self.leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
                                    animated:YES
                              scrollPosition:UITableViewScrollPositionNone];
  1. 初始化左右两侧的tableView
- (UITableView *)leftTableView {
    if (!_leftTableView) {
        _leftTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, leftTableViewWidth, leftTableViewHeight)];
        _leftTableView.delegate = self;
        _leftTableView.dataSource = self;
        _leftTableView.rowHeight = 55;
        _leftTableView.tableFooterView = [UIView new];
        _leftTableView.showsVerticalScrollIndicator = NO;
        _leftTableView.separatorColor = [UIColor clearColor];
        [_leftTableView registerClass:[LeftTableViewCell class] forCellReuseIdentifier:kLeftCellIdentifier];
    }
    return _leftTableView;
}

- (UITableView *)rightTableView {
    if (!_rightTableView) {
        _rightTableView = [[UITableView alloc] initWithFrame:CGRectMake(leftTableViewWidth, 0, SCREEN_WIDTH - leftTableViewWidth, rightTableViewHeight)];
        _rightTableView.delegate = self;
        _rightTableView.dataSource = self;
        _rightTableView.rowHeight = 80;
        _rightTableView.showsVerticalScrollIndicator = NO;
        [_rightTableView registerClass:[RightTableViewCell class] forCellReuseIdentifier:kRightCellIdentifier];
    }
    return _rightTableView;
}
  1. 实现tableView的数据源和代理方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (_leftTableView == tableView)  {#//左侧只有1组
        return 1;
    }
    else {#//右侧的组数 == 左侧的行数
        return self.categoryData.count;
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (_leftTableView == tableView) {
        return self.categoryData.count;
    }
    else  {
        return [self.foodData[section] count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {#//正常逻辑设置cell内容
    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.foodData[indexPath.section][indexPath.row];
        cell.model = model;
        return cell;
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (_rightTableView == tableView)  {#//右侧tableView显示组头
        return 20;
    }
    return 0;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (_rightTableView == tableView)  {
        TableViewHeaderView *view = [[TableViewHeaderView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 20)];
        FoodModel *model = self.categoryData[section];
        view.name.text = model.name;
        return view;
    }
    return nil;
}

下面是最重要的联动环节

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

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

再将右边的 TableView 关联左边的 TableView,这个过程比较繁琐,需要理清逻辑

  1. 先在UISrcollViewDelegate的滚动代理方法里面判断滚动方向
    然后在sectionHeaderView的代理方法里面处理联动效果
  2. 在sectionHeaderView展示结束的代理方法里面,判断RightTableView 滑动的方向向上,而且是用户拖拽而产生滚动的,那么 LeftTableView 的选中行就是 RightTableView 的当前 section + 1。
  3. 在sectionHeaderView即将展示的代理方法里面,判断RightTableView的滑动方向向下,而且是用户拖拽而产生滚动的,那么 LeftTableView 的选中行就是 RightTableView 的当前 section
    清楚这个逻辑之后,下面就好处理了

#pragma mark - UISrcollViewDelegate  第一步判断方向
// 标记一下RightTableView的滚动方向,是向上还是向下
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    static CGFloat lastOffsetY = 0;

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

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

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

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


后期再整理 TableView 与 CollectionView 之间的联动

参考
https://www.jianshu.com/p/7e534656988d
https://github.com/leejayID/Linkage

相关文章

网友评论

      本文标题:UITableView的联动

      本文链接:https://www.haomeiwen.com/subject/lrnpcqtx.html