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

下面是我尝试过的设置:

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

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

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


当前回答

除了以上答案,

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

就是这样。

其他回答

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

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
}

对丹尼尔·加拉斯科的回答做了一些关键的修改,解决了我所有的问题。不幸的是,我还没有足够的声誉来直接评论。

在第一步,当使用自动布局时,简单地添加一个单亲UIView到单元格。单元格内的所有东西都必须是父视图的子视图。这解决了我所有的问题。虽然Xcode会自动为UITableViewCells添加这个,但它不会(但应该)为UICollectionViewCells添加这个。根据文件:

要配置单元格的外观,请在contentView属性的视图中添加将数据项的内容作为子视图显示所需的视图。不要直接向单元格本身添加子视图。

然后完全跳过步骤3。这是不需要的。

在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
    }
}

更新更多信息:

If you use flowLayout.estimatedItemSize, suggest use iOS8.3 later version. Before iOS8.3, it will crash [super layoutAttributesForElementsInRect:rect];. The error message is *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil' Second, in iOS8.x version, flowLayout.estimatedItemSize will cause different section inset setting did not work. i.e. function: (UIEdgeInsets)collectionView:layout:insetForSectionAtIndex:.

对任何可能有帮助的人,

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

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

图。