UICollectionView cell borders in stream layout

I use UICollectionView to lay out a bunch of cells that are separated by the first letter of their name. Each cell should have a very thin border around it, and the section headers should have borders at the top and bottom. Here is my prototype:

Grid of large equally-sized cells, four to a row, with slim light gray headings between sections. Narrow gray borders show the edges of the cells and dividers.

I get the current view with the following rules:

  • Circle the right and bottom edges of each cell.
  • Circle the lower edge of the title of each section.

This is very close to what I want, but there are two drawbacks:

  • If the line before the section heading is not filled, then the border at the top of the heading ends at the right edge of the screen.
  • This is not visible in this screenshot, but if the row is full, the right border of the last cell in the row is still drawn, which looks a bit strange in relation to the edge of the screen.

My best idea to fix this is to somehow say each cell if it is in the last line of a section or the last cell in a line; then the cell will disable the violating borders, in the section headings there will be an upper border, as well as a bottom, and everything will be hard. I do not know how to achieve this.

Any thoughts on how to do this, or another way to get the idea I'm going to? I am currently using UICollectionViewFlowLayout.

+4
source share
3 answers

I finished subclassing UICollectionViewFlowLayout and applied some heuristics after the flow layout computed the attributes for each cell:

  • If center.y is equal to center.y last element in the section, the cell is on the last line of the section.
  • If CGRectGetMaxY(frame) is equal to CGRectGetMaxY(self.collectionView.bounds) , the cell again has the right edge of the collection view.

Then I saved the results of these calculations in a subclass of UICollectionViewLayoutAttributes and wrote a subclass of UICollectionViewCell , whose -applyLayoutAttributes: method will adjust the borders that its background draws based on additional properties.

I put the whole mess in a pretty huge gist so you can see exactly what I did. Happy hack.

+4
source

My best idea to fix this is to somehow say each cell if it is in the last line of a section or the last cell in a line; then the cell will disable the violating borders, in the section headings there will be an upper border, as well as a bottom, and everything will be hard. I do not know how to achieve this.

What you are describing is more or less what I did in a similar scenario. I added the border property to my cell:

 typedef NS_OPTIONS(NSInteger, TLGridBorder) { TLGridBorderNone = 0, TLGridBorderTop = 1 << 0, TLGridBorderRight = 1 << 1, TLGridBorderBottom = 1 << 2, TLGridBorderLeft = 1 << 3, TLGridBorderAll = TLGridBorderTop | TLGridBorderRight | TLGridBorderBottom | TLGridBorderLeft, }; @interface TLGridCellView : UIView @property (nonatomic) TLGridBorder border; @end 

Then I set the border in my controller controller configuration:

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { TLGridCellView *cell = ...; if (indexPath.item == self collectionView:collectionView numberOfItemsInSection:indexPath.section - 1) { cell.border = TLGridBorderLeft; } else { cell.border = TLGridBorderLeft | TLGridBorderRight; } return cell; } 
+3
source

enter image description here

I solve this problem in a simple way. I did not add borders to the cell, instead I add a label with a border to the cell. For the first column, the label frame is the same as the cell. For another shortcut, I set the x -0.5 coordinate to make them overlap the borders. Hope it helps.

Here is the code:

 - (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; // Then use it UILabel *label = nil; if (cell.contentView.subviews.count > 0) { label = cell.contentView.subviews[0]; } else { label = [[UILabel alloc] init]; } label.text = @"εŒ—δΊ¬"; [label setTextAlignment:NSTextAlignmentCenter]; [label setFont:[UIFont systemFontOfSize:14]]; [label setCenter:cell.contentView.center]; CGRect frame = label.frame; if (indexPath.row%4 == 0) { frame.origin.x = 0; } else { frame.origin.x = -0.5; } frame.origin.y = 0; frame.size.width = self.collectionView.frame.size.width / 4; frame.size.height = self.collectionView.frame.size.height / 9; [label setFrame:frame]; if (cell.contentView.subviews.count == 0) { [[cell contentView] addSubview:label]; } label.layer.borderWidth = 0.5; label.layer.borderColor = [[UIColor lightGrayColor] CGColor]; cell.backgroundColor = [UIColor whiteColor]; return cell; } 
+2
source

Source: https://habr.com/ru/post/1490889/


All Articles