UICollectionView不调用intrinsicContentSize

时间:2013-10-14 12:30:27

标签: ios uicollectionview autolayout uicollectionviewlayout

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

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

有关于此的任何想法吗?

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

3 个答案:

答案 0 :(得分:9)

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

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

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

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

这是-intrinsicContentSize的子类化和重写,如果你想增长一个集合视图的框架,直到它被一个兄弟或父视图约束,那么它很有用

答案 1 :(得分:1)

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

更新:我找到了使用intrinsicContentSize执行此操作的方法:UITextView in UIScrollView using auto layout

答案 2 :(得分:0)

使用此类可以在每次更改内容时使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()
        }
    }
}

但是,您应该明白,如果将其嵌入到另一个滚动视图中,则单元格回收将不起作用。处理嵌套集合视图的最受欢迎的方法是here