美文网首页
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