UICollectionView:使用 UIStackView 的动态单元格高度

Posted

技术标签:

【中文标题】UICollectionView:使用 UIStackView 的动态单元格高度【英文标题】:UICollectionView: dynamic cell heights with UIStackView 【发布时间】:2015-11-27 22:13:37 【问题描述】:

我有一个故事板,由单个 UICollectionView 和多个单元格组成,每个单元格的高度各不相同。第一个单元格的高度来自UICollectionViewDelegateFlowLayout

func collectionView(collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize

.. 但我希望第二个单元格更短。 我在单元格内的“主”UIStackView 中放置了两个UIStackViews,每个内部UIStackViews 都有一个或多个标签,如下所示:

cell
--> stackView (master)
    --> stackView (1)
        --> label
    --> stackView (2)
        --> label
        --> label (etc)

.. 希望UIStackView 会使单元格高度动态化,但事实并非如此。它像以前一样从UICollectionViewDelegateFlowLayout 获取高度。

我应该怎么做?

【问题讨论】:

【参考方案1】:

您需要计算CollectionViewCell 的内容大小并将其返回给sizeForItemAt 函数。

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize 

    // Create an instance of the `FooCollectionViewCell`, either from nib file or from code.
    // Here we assume `FooCollectionViewCell` is created from a FooCollectionViewCell.xib
    let cell: FooCollectionViewCell = UINib(nibName: "FooCollectionViewCell", bundle: nil)
        .instantiate(withOwner: nil, options: nil)
        .first as! FooCollectionViewCell

    // Configure the data for your `FooCollectionViewCell`
    cell.stackView.addArrangedSubview(/*view1*/)
    cell.stackView.addArrangedSubview(/*view2*/)

    // Layout the collection view cell
    cell.setNeedsLayout()
    cell.layoutSubviews()

    // Calculate the height of the collection view based on the content
    let size = cell.contentView.systemLayoutSizeFitting(
        CGSize(width: collectionView.bounds.width, height: 0),
        withHorizontalFittingPriority: UILayoutPriorityRequired,
        verticalFittingPriority: UILayoutPriorityFittingSizeLevel)

    return size

有了这个,你将有一个动态的单元格高度UICollectionView


补充说明:

    对于集合视图单元格的配置,您可以在FooCollectionViewCell 上创建一个辅助函数func configure(someData: SomeData),以便在cellForItemAt 函数和sizeForItemAt 函数之间共享代码。

    // Configure the data for your `FooCollectionViewCell`
    cell.stackView.addArrangedSubview(/*view1*/)
    cell.stackView.addArrangedSubview(/*view2*/)
    

    对于这两行代码,似乎只有在 UICollectionViewCell 包含垂直 UIStackView 作为子视图时才需要(可能是来自 Apple 的错误)。

    // Layout the collection view cell
    cell.setNeedsLayout()
    cell.layoutSubviews()
    

【讨论】:

【参考方案2】:

如果您想更改单元格的高度,则必须更改在 sizeForItemAtIndexPath 中返回的高度。堆栈视图在这里不会有任何影响。这是您可以执行的操作的示例:

func collectionView(collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 

    if indexPath.row == 1 
        return CGSizeMake(width, height/2)
    
    return  CGSizeMake(width, height)

这将更改第 1 行单元格的大小。您还可以使用 indexPath.section 来选择部分。希望这会有所帮助。

【讨论】:

以上是关于UICollectionView:使用 UIStackView 的动态单元格高度的主要内容,如果未能解决你的问题,请参考以下文章

iOS 版本特定 info.plist 设置

status barnavigationBartableView吸顶view设置

iOS 流布局 UICollectionView使用(UICollectionVIew的代理方法)

如何使用内部 XIB 为动态 UIStackView 设置对齐方式

UICollectionView介绍使用

使用 NSFetchResultsController 时 UICollectionView 滚动不流畅