我试图得到自我大小UICollectionViewCells工作与自动布局,但我似乎不能让单元格大小自己的内容。我很难理解如何从单元格的contentView内的内容更新单元格的大小。

下面是我尝试过的设置:

自定义UICollectionViewCell,在它的contentView中有一个UITextView。 UITextView的滚动被禁用。 contentView的水平约束是:"H:|[_textView(320)]",也就是说UITextView被固定在单元格的左边,显式宽度为320。 contentView的垂直约束是:"V:|-0-[_textView]",也就是说UITextView固定在单元格的顶部。 UITextView有一个高度约束设置为常数,UITextView报告将适合文本。

下面是单元格背景设置为红色,UITextView背景设置为蓝色时的效果:

我把我一直在GitHub上玩的项目放在这里。


当前回答

上面的示例方法不能编译。以下是更正后的版本(但未经测试是否有效)。

override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes 
{
    let attr: UICollectionViewLayoutAttributes = layoutAttributes.copy() as! UICollectionViewLayoutAttributes

    var newFrame = attr.frame
    self.frame = newFrame

    self.setNeedsLayout()
    self.layoutIfNeeded()

    let desiredHeight: CGFloat = self.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
    newFrame.size.height = desiredHeight
    attr.frame = newFrame
    return attr
}

其他回答

在iOS10中有一个名为UICollectionViewFlowLayout的新常量。automaticSize(以前的UICollectionViewFlowLayoutAutomaticSize),所以改为:

self.flowLayout.estimatedItemSize = CGSize(width: 100, height: 100)

你可以用这个:

self.flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize

它具有更好的性能,特别是当集合视图中的单元格具有恒定宽度时。

访问流布局:

override func viewDidLoad() {
   super.viewDidLoad()

   if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
      flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
   }
}

Swift 5更新:

override func viewDidLoad() {
   super.viewDidLoad()

   if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
      flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
    }
}

对任何可能有帮助的人,

如果设置了estimatedItemSize,我就会发生严重的崩溃。即使我在numberOfItemsInSection中返回0。因此,单元格本身和它们的自动布局不是导致崩溃的原因……collectionView刚刚崩溃,即使是空的,这只是因为estimatedItemSize被设置为自大小。

在我的例子中,我重新组织了我的项目,从一个包含collectionView的控制器到一个collectionViewController,它工作了。

图。

对于那些尝试一切都没有运气的人来说,这是唯一让它为我工作的东西。 对于单元格内的多行标签,尝试添加以下神奇的行:

label.preferredMaxLayoutWidth = 200

更多信息:点击这里

干杯!

在Swift 5中,它适用于我。

UICollectionViewFlowLayout:

estimatedItemSize = UICollectionViewFlowLayout.automaticSize

UICollectionViewCell:

(ps:我用的是SnapKit)

class Cell: UICollectionViewCell {
    let customizedContentView = UIView()
    ...
    func layoutAction() {
        contentView.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(customizedContentView)
        customizedContentView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
}

然后你只需要展开customizedContentView。

除了以上答案,

只要确保你将UICollectionViewFlowLayout的estimatedItemSize属性设置为某个大小,而不实现sizeForItem:atIndexPath委托方法。

就是这样。