问题描述
我正在尝试在我的 UICollectionView中的
我不知道怎么做。我正在努力做到这样的事情: UICollectionViewCell
之间添加 UIView
我可能需要写一个自定义的 UICollectionViewLayout
,但我真的不知道在哪里我开始研究 UICollectionViewLayout
的工作原如何解决它。我有一个名为 OrangeView
的 UICollectionReusableView
子类,它位于我的视图之间,而不是我写的 UICollectionViewFlowLayout
子类名为 CategoriesLayout
,它将处理我的布局。
对不起大块的代码,但这是它的样子:
@implementation CategoriesLayout
- ( void)prepareLayout {
//注册我的装饰视图。
[self registerClass:[OrangeView class] forDecorationViewOfKind:@Vertical];
[self registerClass:[OrangeView class] forDecorationViewOfKind:@Horizontal];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath {
//准备一些变量。
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;
//定位此项目的垂直线。
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 {
//定位此项目的水平线。
layoutAttributes.frame = CGRectMake(baseFrame.origin.x,
baseFrame.origin.y + baseFrame.size.height,
baseFrame.size.width + spaceToNextItem,
strokeWidth) ;
}
layoutAttributes.zIndex = -1;
返回layoutAttributes;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray * baseLayoutAttributes = [super layoutAttributesForElementsInRect:rect];
NSMutableArray * layoutAttributes = [baseLayoutAttributes mutableCopy];
for(UICollectionViewLayoutAttributes * thisLayoutItem in baseLayoutAttributes){
if(thisLayoutItem.representedElementCategory == UICollectionElementCategoryCell){
//当项不是最后一项时添加垂直线部分或排队。
if(!([self indexPathLastInSection:thisLayoutItem.indexPath] ||
[self indexPathLastInLine:thisLayoutItem.indexPath])){
UICollectionViewLayoutAttributes * newLayoutItem = [self layoutAttributesForDecorationViewOfKind:@VerticalatIndexPath :thisLayoutItem.indexPath];
[layoutAttributes addObject:newLayoutItem];
}
//当项目不在最后一行时添加水平线。
if(![self indexPathInLastLine:thisLayoutItem.indexPath]){
UICollectionViewLayoutAttributes * newHorizontalLayoutItem = [self layoutAttributesForDecorationViewOfKind:@HorizontalatIndexPath:thisLayoutItem.indexPath];
[layoutAttributes addObject:newHorizontalLayoutItem];
}
}
}
返回layoutAttributes;
}
@end
我还写了一个类别一些方法来检查索引路径是否是一行中的最后一行,最后一行或部分中的最后一行:
@implementation UICollectionViewFlowLayout(Helpers)
- (BOOL)indexPathLastInSection:(NSIndexPath *)indexPath {
NSInteger lastItem = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section] -1;
返回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];
返回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
这是最终结果:
I'm trying to add UIView
s between my UICollectionViewCell
s in my UICollectionView
and I don't know how I could do that. I'm trying to accomplish something like this:
I'll probably need to write a custom UICollectionViewLayout
, but I don't really know where to start.
I studied more of how UICollectionViewLayout
s work and figured out how to solve it. I have an UICollectionReusableView
subclass called OrangeView
that will be positioned between my views, than I wrote an UICollectionViewFlowLayout
subclass called CategoriesLayout
that will deal with my layout.
Sorry for the big block of code, but here is how it looks like:
@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
I also wrote a category with some methods to check if an index path is the last in a line, in the last line or the last in a section:
@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
And this is the final result:
这篇关于如何在UICollectionView中的UICollectionViewCells之间添加视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!