如何用列和行标题创buildUICollectionView?

我想创build一个如下所示的UICollectionView:

是的。这个。

它不会被滚动或编辑。 我目前想知道如何编写这个布局。 我猜它不会是UICollectionViewFlowLayout的子类。 我可以想到很多方法,但是如果有任何“正确的”方法,我们会好奇的。 这些单元格将具有animation能力。

每行或每列应该是自己的部分?

我已经做了像你想要的东西与UICollectionViewFlowLayout的子类。 看起来像这样

  @implementation MultpleLineLayout { NSInteger itemWidth; NSInteger itemHeight; } -(id)init { if (self = [super init]) { itemWidth = 80; itemHeight = 80; } return self; } -(CGSize)collectionViewContentSize { NSInteger xSize = [self.collectionView numberOfItemsInSection:0] * (itemWidth + 2); // the 2 is for spacing between cells. NSInteger ySize = [self.collectionView numberOfSections] * (itemHeight + 2); return CGSizeMake(xSize, ySize); } - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path { UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]; NSInteger xValue; attributes.size = CGSizeMake(itemWidth,itemHeight); xValue = itemWidth/2 + path.row * (itemWidth +2); NSInteger yValue = itemHeight + path.section * (itemHeight +2); attributes.center = CGPointMake(xValue, yValue); return attributes; } -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { NSInteger minRow = (rect.origin.x > 0)? rect.origin.x/(itemWidth +2) : 0; // need to check because bounce gives negative values for x. NSInteger maxRow = rect.size.width/(itemWidth +2) + minRow; NSMutableArray* attributes = [NSMutableArray array]; for(NSInteger i=0 ; i < self.collectionView.numberOfSections; i++) { for (NSInteger j=minRow ; j < maxRow; j++) { NSIndexPath* indexPath = [NSIndexPath indexPathForItem:j inSection:i]; [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]]; } } return attributes; } 

数据按arrays排列,其中每个内部arrays提供一个水平行的数据。 用我现在的价值观,并以你的数据为例,视图看起来像这样,

在这里输入图像说明

这是我没有视图控制器的代码,

 @interface ViewController () @property (strong,nonatomic) UICollectionView *collectionView; @property (strong,nonatomic) NSArray *theData; @end @implementation ViewController - (void)viewDidLoad { self.theData = @[@[@"",@"A",@"B",@"C"],@[@"1",@"115",@"127",@"132"],@[@"2",@"",@"",@"153"],@[@"3",@"",@"199",@""]]; MultpleLineLayout *layout = [[MultpleLineLayout alloc] init]; self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; self.collectionView.dataSource = self; self.collectionView.delegate = self; layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; self.view.backgroundColor = [UIColor blackColor]; [self.view addSubview:self.collectionView]; [self.collectionView registerNib:[UINib nibWithNibName:@"CustomDataCell" bundle:nil] forCellWithReuseIdentifier:@"DataCell"]; } - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section { return [self.theData[section] count]; } - (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView { return [self.theData count]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { DataCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"DataCell" forIndexPath:indexPath]; cell.label.text = self.theData[indexPath.section][indexPath.row]; return cell; } 

你可以用UICollectionViewFlowLayout来完成,但是如果你这样做的话,你需要仔细计算,并得到填充(即左上angular,和其他“空”单元格)的权利。 如果你算错了,这很明显,因为这个stream程很快就会把所有东西都毁掉,你会在你的列中find你的标题单元格。 (我做了类似的事情)

我只是这样做,因为担心自定义布局 – 但事实上,它就像UITableView一样简单。 如果你的布局根本不滚动,那么你的特别简单,因为你唯一真正的工作就是计算单元格的帧值,在layoutAttributesForItemAtIndexPath返回。 由于您的整个视图适合可见区域,因此layoutAttributesForElementsInRect将意味着您只需遍历视图中的所有单元格。 collectionViewContentSize将是你的视图的大小。

看看你的示例图片,你可能会发现把数据组织成一个数组字典,每列一个数据就很方便。 您可以按名称(“A”,“B”等)获取列数组,并且数组中的位置与最左列中的值相对应,您可以将其命名为“index”。

还有更多的方法可以使用,但这些都是基础知识,并且会使您的基本显示正常运行。