UICollectionViewLayout 示例

Posted

技术标签:

【中文标题】UICollectionViewLayout 示例【英文标题】:UICollectionViewLayout Examples 【发布时间】:2012-11-13 12:41:55 【问题描述】:

谁能指出我如何使用 UICollectionViewLayout 创建类似于 Pinterest 列布局的界面?

我尝试在网上搜索,但似乎还没有很多示例。

【问题讨论】:

【参考方案1】:

1000memories “Quilt” 视图类似于 pinterest 并且是开源的:http://blog.1000memories.com/168-opensourcing-quilt,您可以深入了解它是如何工作的。

如果您正在寻找更概念性的概述,这里是您想要做什么的基本概念。到目前为止,如果您只需要 Pinterest 样式的布局,最简单的事情就是继承 UICollectionViewFlowLayout。你可以从这个类中获得很多布局帮助,Pinterest 风格在它的能力范围内。你只需要重写一个方法。

使用 UICollectionViewFlow 布局设置一个普通的 UICollectionView。一个快速的方法是:

将 UIViewController 拖到情节提要上,然后将 UICollectionView 拖放到上面。设置类以匹配您的自定义类等。您可以在此处使用委托并创建一个委托类,但严格来说,这不是实现 Pinterest 流布局所必需的(您几乎肯定希望将选择责任的内容分解为但实际上是委托类)。 存根数据源。为 UICollectionView (http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewDataSource_protocol/Reference/Reference.html) 实现数据源协议非常简单。确保在 UICollectionViewCell 上设置重用标识符。你需要:
    (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 现在只返回 1; (NSInteteger)collectionView:numberOfItemsInSection: 现在硬编码一个数字,设为 20。 ——(UICollectionViewCell *)collectionView:cellForItemAtIndexPath: 这是对流布局进行子类化的地方之一。您在这里真正需要做的就是使用索引路径调用dequeueReusableCellWithReuseIdentifier:forIndexPath:。如果您向单元格添加了 UIImageView 或一些标签,这将是实际分配图像、文本等的好地方。

在 viewController 的 viewDidLoad 中实例化一个 UICollectionViewFlowLayout 并将 UICollectionView 的数据源设置为您的,并将布局设置为 flowlayout。请记住,这个类是UICollectionViewViewController 的子类。

self.collectionView.dataSource = [[YourDataSource alloc] init];
self.collectionView.collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];

好的。此时,您应该能够运行您的应用程序并在屏幕上看到一些内容。这是一个旋风式的概述。如果您需要有关如何设置 ViewController 等的更多详细信息,有大量可用的相关资料。

现在是重要的部分,Pinterest 化流布局。

首先,添加一个新类,它是 UIViewControllerFlowLayout 的子类。更改 ViewController 的 viewDidLoad 以实例化此类并指定为 UICollectionViewcollectionViewLayout

您需要实现的方法是- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

事情是这样的:超类将为您完成几乎所有的工作。您的代码将如下所示:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

    NSArray *attributes = [super layoutAttributesForElementsInRect:rect]; 
    [attributes enumerateObjectsUsingBlock:^(id attr, NSUInteger idx, BOOL *stop) 
    float newYCoord = [calculationMethodYouHaveToWriteFor:attr.frame];
    attr.frame = CGRectMake(attr.frame.origin.x, newYCoord, attr.size.width, attr.size.height];
];


Pinterest 使用固定宽度的列,您在计算方法中所需要做的就是找出您所在的列(`attr.origin.x / _columnWidth),并从 ivar 中查找该列的总高度你一直在保存它。不要忘记将它添加到新对象的高度并保存它以供下一次传递。

流布局超类处理:制作单元格,确定哪些单元格可见,确定内容大小,确定行在 x 方向上的排列,为单元格分配索引路径。很多垃圾。覆盖这种方法可以让您根据自己的心愿摆弄 y-pos。

【讨论】:

此时我得到一个零数组 NSArray *attributes = [super layoutAttributesForElementsInRect:rect]; .如果我不覆盖 collectionViewLayout,我的收藏视图就会显示出来【参考方案2】:

来自github的两个

https://github.com/jayslu/JSPintDemo

https://github.com/chiahsien/UICollectionViewWaterfallLayout

我现在在一个项目中使用了 Waterfall 的修改版本,我现在正在研究 JSPint。

【讨论】:

【参考方案3】:

我创建了一个自定义 uicollectionviewlayout,用于我的个人项目。链接在这里。希望能帮助到你。

https://github.com/johnny0614/YJZAlbumCollectionViewLayout

【讨论】:

【参考方案4】:

你可以从这里得到任何你想要的东西: https://github.com/ParsifalC/CPCollectionViewKit 例如(这两种布局都是自定义的UICollectionViewLayout):

【讨论】:

以上是关于UICollectionViewLayout 示例的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionViewLayout '冻结'

UICollectionViewLayout 教程

我应该继承啥 UICollectionViewLayout 或 UICollectionViewFlowLayout

UICollectionViewLayout - 2 列中的 3 个单元格

为啥将 UICollectionViewLayout 分配给 UICollectionView 后 UICollectionViewCells 不再可见?

自定义 UICollectionViewLayout 不同的单元格大小