UICollectionView自定义行分隔符 [英] UICollectionView custom line separators

查看:105
本文介绍了UICollectionView自定义行分隔符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 UICollectionView 中为我们的新应用制作 2pt黑色分隔符。我们的应用程序截图如下。我们无法使用 UITableView ,因为我们有自定义插入/删除动画,滚动和视差效果等等。

I wanna making 2pt black separators in UICollectionView for our new app. Screenshot from our app is below. We couldn't use UITableView, because we have custom insert/delete animations, scrolling and parallax effects and so on.

推荐答案

我从三个想法开始如何制作它:

I started with three ideas how to make it:


  • 在单元格中实现这些分隔符

  • 使用纯黑色背景 minimumLineSpacing ,因此我们会在单元格之间的空格中看到背景

  • 使用自定义布局并将此分隔符实现为装饰

  • implement these separators right inside the cells
  • use solid black background with minimumLineSpacing, thus we will see background in spaces between cells
  • use custom layout and implement this separators as decorations

前两个变体被拒绝是因为意识形态不一致,自定义动画以及收集下面的内容。此外,我已经有了自定义布局。

First two variants were rejected because ideologic inconsistency, custom animations and having content below collection. Also I already have a custom layout.

我将描述使用 UICollectionViewFlowLayout 的自定义子类的步骤。

I will describe the steps with a custom subclass of UICollectionViewFlowLayout.

实施自定义 UICollectionReusableView 子类。

@interface FLCollectionSeparator : UICollectionReusableView

@end

@implementation FLCollectionSeparator

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor blackColor];
    }

    return self;
}

- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    self.frame = layoutAttributes.frame;
}

@end



- 2 -



说布局使用自定义装饰。还要在单元格之间建立行间距。

--2--

Say layout to use custom decorations. Also make line spacing between cells.

UICollectionViewFlowLayout* layout = (UICollectionViewFlowLayout*) self.newsCollection.collectionViewLayout;
[layout registerClass:[FLCollectionSeparator class] forDecorationViewOfKind:@"Separator"];
layout.minimumLineSpacing = 2;



- 3 -



In自定义 UICollectionViewFlowLayout 子类我们应该从 layoutAttributesForElementsInRect 返回装饰 UICollectionViewLayoutAttributes

--3--

In custom UICollectionViewFlowLayout subclass we should return UICollectionViewLayoutAttributes for decorations from layoutAttributesForElementsInRect.

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    ... collect here layout attributes for cells ... 

    NSMutableArray *decorationAttributes = [NSMutableArray array];
    NSArray *visibleIndexPaths = [self indexPathsOfSeparatorsInRect:rect]; // will implement below

    for (NSIndexPath *indexPath in visibleIndexPaths) {
        UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForDecorationViewOfKind:@"Separator" atIndexPath:indexPath];
        [decorationAttributes addObject:attributes];
    }

    return [layoutAttributesArray arrayByAddingObjectsFromArray:decorationAttributes];
}



- 4 -



对于可见的rect,我们应该返回可见的装饰索引pathes。

--4--

For visible rect we should return visible decorations index pathes.

- (NSArray*)indexPathsOfSeparatorsInRect:(CGRect)rect {
    NSInteger firstCellIndexToShow = floorf(rect.origin.y / self.itemSize.height);
    NSInteger lastCellIndexToShow = floorf((rect.origin.y + CGRectGetHeight(rect)) / self.itemSize.height);
    NSInteger countOfItems = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];

    NSMutableArray* indexPaths = [NSMutableArray new];
    for (int i = MAX(firstCellIndexToShow, 0); i <= lastCellIndexToShow; i++) {
        if (i < countOfItems) {
            [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        }
    }
    return indexPaths;
}



- 5 -



我们还应该实现 layoutAttributesForDecorationViewOfKind

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath];
    CGFloat decorationOffset = (indexPath.row + 1) * self.itemSize.height + indexPath.row * self.minimumLineSpacing;
    layoutAttributes.frame = CGRectMake(0.0, decorationOffset, self.collectionViewContentSize.width, self.minimumLineSpacing);
    layoutAttributes.zIndex = 1000;

    return layoutAttributes;
}



- 6 -



有时我发现这个解决方案给出了装饰外观的视觉故障,通过实现 initialLayoutAttributesForAppearingDecorationElementOfKind 来修复。

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)decorationIndexPath {
    UICollectionViewLayoutAttributes *layoutAttributes =  [self layoutAttributesForDecorationViewOfKind:elementKind atIndexPath:decorationIndexPath];
    return layoutAttributes;
}

这就是全部。没有太多的代码,但做得很好。

That's all. Not too much code but done right.

这篇关于UICollectionView自定义行分隔符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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