iOS - TableView linkage and CollectionView

Preface:

TableView and CollectionView we often use controls, set up the page with the most is that they make no foot hand we also measures which, between us and them is filled with both good and bad. This article is mainly talking about the collaboration between them, the linkage function. If the poor coordination between them, with contradictions, always hurt us.

FIG effect as GIF

2156697-269610eacee64905.gif

FIG static effect as FIG.

2156697-17969c37f7fb0649.png

Fundamental Analysis

First, we pass the page to analyze. Such requirements are, TableView a category list on the left, the right side corresponds to the content classification CollectionView, Item plurality of blocks. To put it plainly is classified a large item, corresponding to a plurality of N classification lesser term of one to many relationship.


Sort function point

 - 1.默认左边TableView显示第一个分类,右边CollectionView显示第一个分类的内容。
 - 2.点击左边TableView任意一个分类时,右边CollectionView滚动至当前分类所对应的内容。
 - 3.滚动右边CollectionView分类内容时,左边列表TableView会实时滚动到右边内容所对应的分类标题。
 - 4.当滚动右边CollectionView内容停下时,左边列表TableView会选中对应的CollectionView内容的标题。

Building a data structure

This is the type of style

 NSArray *dataSource = @[
                  @{@"title":@"One1",
                  @"list" :@[@"a",@"b",@"c"],
                  @"imgs" :@[@"a_img",@"b_img",@"c_img"]},

                  @{@"title":@"One2",
                  @"list" :@[@"a",@"b",@"c"],
                  @"imgs" :@[@"a_img",@"b_img",@"c_img"]}

                  @{@"title":@"One3",
                  @"list" :@[@"a",@"b",@"c"],
                  @"imgs" :@[@"a_img",@"b_img",@"c_img"]}
                ];

Core logic

001 is selected by default

      // 默认选中
      NSIndexPath *firstPath = [NSIndexPath indexPathForRow:0 inSection:0];
      [self.leftTableView selectRowAtIndexPath:firstPath animated:YES scrollPosition:UITableViewScrollPositionNone];
      if ([self.leftTableView.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]) {
          [self.leftTableView.delegate tableView:self.leftTableView didSelectRowAtIndexPath:firstPath];
      }
      
      [self.rightCollectionView selectItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionNone];
      if ([self.rightCollectionView.delegate respondsToSelector:@selector(collectionView:didSelectItemAtIndexPath:)]) {
          [self.rightCollectionView.delegate collectionView:self.rightCollectionView didSelectItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
      }

When entering the page, select the default state is 0 Group 0.

002 Click on the left list control to the right collectionView

 - (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated{

     CGRect headerRect = [self frameForHeaderForSection:section];
     // scrollview的contentview的顶点相对于scrollview的位置。
     CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y-self.rightCollectionView.contentInset.top);
     [self.rightCollectionView setContentOffset:topOfHeader animated:animated];

 }

When we click on the left list any title, the corresponding content on the right collectionViewe will scroll to the top of the page. In fact, when we click on the left is the title, the corresponding offset change collectionView make collectioVIew scroll.

   -(CGRect)frameForHeaderForSection:(NSInteger)section{
      
      NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:section];
      // 返回每一个item的布局属性
      UICollectionViewLayoutAttributes *attributes = [self.rightCollectionView layoutAttributesForItemAtIndexPath:indexPath];
      CGRect frameForFirstCell = attributes.frame;
      
      // 求出第某组section数据HeaderView尺寸的高度
      CGFloat headerHeight = [self collectionView:self.rightCollectionView layout:self.flowLayout referenceSizeForHeaderInSection:section].height;
      UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)self.rightCollectionView.collectionViewLayout;
      // 求出距离顶部的内边距
      CGFloat cellTopEdge = flowLayout.sectionInset.top;
      /*
       相对于源矩形原点(左上角的点)沿x轴和y轴偏移
       */
      return CGRectOffset(frameForFirstCell, 0, -headerHeight-cellTopEdge);
      
  }

We know that according to the needs, collectionView are grouped. Then how do we obtain the correct offset it?

When we click on a title, we know the number of lines corresponding to a title, a number of groups corresponding to the right collectionView. When we click on the title, you can obtain an offset collectionView a group of the right to return, let collectionView scroll up. Because of the head group, by this method, CGRectOffset we need to calculate the offset of a group, a group from the top left direction, the head group height offset. In this way, we will know collectionView offset CGRectOffset (frameForFirstCell, 0, -headerHeight-cellTopEdge); how much, plus collectionView top padding, it accurate.

003 slide list on the right, left control of the selected title

When we scroll to the right content, we want to know whether the right content is slipping, and whether it is being dragged.

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
 {
     static float lastOffSetY = 0;
     if(self.rightCollectionView == scrollView) {
     
         self.isScrollDown = lastOffSetY < scrollView.contentOffset.y;
         lastOffSetY = scrollView.contentOffset.y;  
     }  
 }

When the cell occurs, we move up, and drag, we retrieved selectRowAtIndexPath method of controlling the number of rows in the list on the left to scroll the selected group corresponding to the number. When the cell will appear, and when the cell has emerged called.

  -(void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
      
      if (!self.isScrollDown && collectionView.dragging) {
          [self selectRowAtIndexPath:indexPath.section];
      }
  }

  -(void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
      if (self.isScrollDown && collectionView.dragging) {
          [self selectRowAtIndexPath:indexPath.section];
      }
  }

  -(void)selectRowAtIndexPath:(NSInteger)index{

      [self.leftTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] animated:YES scrollPosition:UITableViewScrollPositionMiddle];

  }

If you have any good suggestions, can communicate with each other to promote, thank you ~

Reproduced in: https: //www.jianshu.com/p/8f4bae3022a7

Guess you like

Origin blog.csdn.net/weixin_33978044/article/details/91283248