2

我有一个UICollectionViewController生成随机颜色的单元格用于测试目的。既然UICollectionViewController嵌入在 a 中UIScrollView,我希望 scrollView 的大小与它的大小相同contentSize

我创建了一个子类UICollectionView,实现了intrinsicContentSize方法,并将UICollectionView' 的类设置为我在 IB 中的自定义类。但是intrinsicContentSize永远不会被调用。我有与 an 完全相同的设置,UITableView并且它可以完美地工作。

对此有什么想法吗?

- (CGSize)intrinsicContentSize {
    [self layoutIfNeeded];
    return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
}
4

3 回答 3

14

正确的答案是做这样的事情

- (CGSize)intrinsicContentSize
{
    return self.collectionViewLayout.collectionViewContentSize;
}

并在您认为需要更改时调用 -invalidateContentSize(例如在 reloadData 之后)。

在 Interface Builder 中,您可能需要设置占位符固有大小约束以避免错误。

如果您想扩大集合视图的框架直到它受到兄弟视图或父视图的约束,这种 -intrinsicContentSize 的子类化和覆盖非常有用

于 2016-01-25T22:55:10.987 回答
1

我不确定为什么会这样。这是此问题的另一种解决方案。设置UICollectionView对象的高度约束。然后将其设置constant为等于self.collectionView.contentSize.height。我在我的应用程序中使用了类似的方法,尽管我有UITextView而不是UICollectionView.

更新:我找到了一种方法来做到这一点intrinsicContentSizeUIScrollView 中的 UITextView 使用自动布局

于 2013-10-15T08:44:31.187 回答
-1

使用此类使 UICollectionView 在每次内容更改时更新其内在内容大小。

class AutosizedCollectionView: UICollectionView {
    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
        super.init(frame: frame, collectionViewLayout: layout)
        registerObserver()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        registerObserver()
    }

    deinit {
        unregisterObserver()
    }

    override var intrinsicContentSize: CGSize {
        return contentSize
    }

    private func registerObserver() {
        addObserver(self, forKeyPath: #keyPath(UICollectionView.contentSize), options: [], context: nil)
    }

    private func unregisterObserver() {
        removeObserver(self, forKeyPath: #keyPath(UICollectionView.contentSize))
    }

    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?)
    {
        if keyPath == #keyPath(UICollectionView.contentSize) {
            invalidateIntrinsicContentSize()
        }
    }
}

不过,您应该明白,如果将其嵌入到另一个滚动视图中,则单元格回收将不起作用。此处描述了处理嵌套集合视图的最受赞赏的方法。

于 2018-01-11T06:10:25.047 回答