如何在UICollectionView中的UICollectionViewCells之间添加视图? [英] How to add views between UICollectionViewCells in a UICollectionView?

查看:100
本文介绍了如何在UICollectionView中的UICollectionViewCells之间添加视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的 UICollectionView中的 UICollectionViewCell 之间添加 UIView 我不知道怎么做。我正在努力做到这样的事情:





我可能需要写一个自定义的 UICollectionViewLayout ,但我真的不知道在哪里我开始研究 UICollectionViewLayout 的工作原如何解决它。我有一个名为 OrangeView UICollectionReusableView 子类,它位于我的视图之间,而不是我写的 UICollectionViewFlowLayout 子类名为 CategoriesLayout ,它将处理我的布局。



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

  @implementation CategoriesLayout 

- ( void)prepareLayout {
//注册我的装饰视图。
[self registerClass:[OrangeView class] forDecorationViewOfKind:@Vertical];
[self registerClass:[OrangeView class] forDecorationViewOfKind:@Horizo​​ntal];
}

- (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 * newHorizo​​ntalLayoutItem = [self layoutAttributesForDecorationViewOfKind:@Horizo​​ntalatIndexPath:thisLayoutItem.indexPath];
[layoutAttributes addObject:newHorizo​​ntalLayoutItem];
}
}
}

返回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 UIViews between my UICollectionViewCells 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 UICollectionViewLayouts 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之间添加视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆