如何在UICollectionView中的UICollectionViewCells之间添加视图?

我想在我的UICollectionViewCell中的UICollectionView之间添加UIView s,我不知道我该怎么做。 我试图做到这样的事情:

截图

我可能需要编写一个自定义的UICollectionViewLayout ,但我真的不知道从哪里开始。

我研究了如何UICollectionViewLayout的工作,并找出如何解决它。 我有一个名为OrangeViewUICollectionReusableView子类,它将被定位在我的视图之间,比我写一个名为CategoriesLayoutUICollectionViewFlowLayout子类将处理我的布局。

对不起,大块的代码,但这是它的样子:

 @implementation CategoriesLayout - (void)prepareLayout { // Registers my decoration views. [self registerClass:[OrangeView class] forDecorationViewOfKind:@"Vertical"]; [self registerClass:[OrangeView class] forDecorationViewOfKind:@"Horizontal"]; } - (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath { // Prepare some variables. NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:indexPath.row+1 inSection:indexPath.section]; UICollectionViewLayoutAttributes *cellAttributes = [self layoutAttributesForItemAtIndexPath:indexPath]; UICollectionViewLayoutAttributes *nextCellAttributes = [self layoutAttributesForItemAtIndexPath:nextIndexPath]; UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath]; CGRect baseFrame = cellAttributes.frame; CGRect nextFrame = nextCellAttributes.frame; CGFloat strokeWidth = 4; CGFloat spaceToNextItem = 0; if (nextFrame.origin.y == baseFrame.origin.y) spaceToNextItem = (nextFrame.origin.x - baseFrame.origin.x - baseFrame.size.width); if ([decorationViewKind isEqualToString:@"Vertical"]) { CGFloat padding = 10; // Positions the vertical line for this item. CGFloat x = baseFrame.origin.x + baseFrame.size.width + (spaceToNextItem - strokeWidth)/2; layoutAttributes.frame = CGRectMake(x, baseFrame.origin.y + padding, strokeWidth, baseFrame.size.height - padding*2); } else { // Positions the horizontal line for this item. layoutAttributes.frame = CGRectMake(baseFrame.origin.x, baseFrame.origin.y + baseFrame.size.height, baseFrame.size.width + spaceToNextItem, strokeWidth); } layoutAttributes.zIndex = -1; return layoutAttributes; } - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *baseLayoutAttributes = [super layoutAttributesForElementsInRect:rect]; NSMutableArray * layoutAttributes = [baseLayoutAttributes mutableCopy]; for (UICollectionViewLayoutAttributes *thisLayoutItem in baseLayoutAttributes) { if (thisLayoutItem.representedElementCategory == UICollectionElementCategoryCell) { // Adds vertical lines when the item isn't the last in a section or in line. if (!([self indexPathLastInSection:thisLayoutItem.indexPath] || [self indexPathLastInLine:thisLayoutItem.indexPath])) { UICollectionViewLayoutAttributes *newLayoutItem = [self layoutAttributesForDecorationViewOfKind:@"Vertical" atIndexPath:thisLayoutItem.indexPath]; [layoutAttributes addObject:newLayoutItem]; } // Adds horizontal lines when the item isn't in the last line. if (![self indexPathInLastLine:thisLayoutItem.indexPath]) { UICollectionViewLayoutAttributes *newHorizontalLayoutItem = [self layoutAttributesForDecorationViewOfKind:@"Horizontal" atIndexPath:thisLayoutItem.indexPath]; [layoutAttributes addObject:newHorizontalLayoutItem]; } } } return layoutAttributes; } @end 

我也写了一些方法来检查索引path是最后一行还是最后一行的最后一行:

 @implementation UICollectionViewFlowLayout (Helpers) - (BOOL)indexPathLastInSection:(NSIndexPath *)indexPath { NSInteger lastItem = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section] -1; return lastItem == indexPath.row; } - (BOOL)indexPathInLastLine:(NSIndexPath *)indexPath { NSInteger lastItemRow = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section] -1; NSIndexPath *lastItem = [NSIndexPath indexPathForItem:lastItemRow inSection:indexPath.section]; UICollectionViewLayoutAttributes *lastItemAttributes = [self layoutAttributesForItemAtIndexPath:lastItem]; UICollectionViewLayoutAttributes *thisItemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath]; return lastItemAttributes.frame.origin.y == thisItemAttributes.frame.origin.y; } - (BOOL)indexPathLastInLine:(NSIndexPath *)indexPath { NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:indexPath.row+1 inSection:indexPath.section]; UICollectionViewLayoutAttributes *cellAttributes = [self layoutAttributesForItemAtIndexPath:indexPath]; UICollectionViewLayoutAttributes *nextCellAttributes = [self layoutAttributesForItemAtIndexPath:nextIndexPath]; return !(cellAttributes.frame.origin.y == nextCellAttributes.frame.origin.y); } @end 

这是最后的结果:

最后结果

如果您使用的部分和布局适合它,您可以使用部分页眉和页脚。

但是根据你的例子,看起来你只需要定义UICollectionViewCell来包含这些视图。 所以,你在哪里注册你的class级:

 [collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"Cell"]; 

把这些边界图像放在UICollectionView单元格子类中(在上面的例子中是“CollectionViewCell”)。 这似乎是最简单的方法。

以下是我使用的一个:

 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.restorationIdentifier = @"Cell"; self.backgroundColor = [UIColor clearColor]; self.autoresizingMask = UIViewAutoresizingNone; const CGFloat borderWidth = 3.0f; UIView *bgView = [[UIView alloc] initWithFrame:frame]; bgView.layer.borderColor = [UIColor blackColor].CGColor; bgView.layer.borderWidth = borderWidth; bgView.layer.cornerRadius = 6.0f; self.selectedBackgroundView = bgView; } return self; } 

看起来如果你的collectionView背景是绿色的而contentView是白色的,你可以在单元格minimumLineSpacing之间获得一个空格。 纵向差距将是棘手的部分,但如果你有创意的contentView,并仔细设置minimumInteritemSpacing你可以得到它。

首先,您必须为收集单元设置边缘插页,然后您必须以编程方式设置分隔视图的框架

 - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(ITEM_SPACING, ITEM_SPACING, ITEM_SPACING, ITEM_SPACING); } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UIView *seperatorView = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.origin.x, cell.frame.origin.y+cell.frame.size.height, cell.frame.size.width, 2)]; seperatorView.backgroundColor = [UIColor grayColor]; [collectionView addSubview:seperatorView]; [collectionView bringSubviewToFront:seperatorView]; } 

哇。 这是其他答案中的很多代码,仅用于行之间的分隔符行。

这就是我解决它的方法。 首先,您需要在单元格内添加行分隔符。 确保你继续拖动它比实际的单元格宽度更宽,所以如果你的单元格宽度是60p,你的分隔线将是70。

 @implementation CollectionViewController { NSArray *test; int currentLocInRow; } 

cellForItemAtIndexPath里面:

 if((indexPath.row+1) % 4 == 0) { cell.clipsToBounds = YES; } else { cell.clipsToBounds = NO; } currentLocInRow++; if([test count] - indexPath.row+1 < 4 - currentLocInRow) { cell.lineSeparator.alpha = 0; } else { cell.lineSeparator.alpha = 1; } if(currentLocInRow==4)currentLocInRow=0; 

在这里输入图像说明

如果您希望在收集视图末尾有一个分隔符,但有可能在最后一行中不能获得4个单元格,您可以添加一个简单的可重复使用collections集作为页脚。