简体   繁体   English

UICollectionView不调用intrinsicContentSize

[英]UICollectionView not calling intrinsicContentSize

I have a UICollectionViewController which generates cells with a random color for testing purposes. 我有一个UICollectionViewController ,它生成一个随机颜色的单元格用于测试目的。 Now that the UICollectionViewController is embedded in a UIScrollView , I want the scrollView to be the same size as it's contentSize . 现在UICollectionViewController嵌入在UIScrollView ,我希望scrollView与它的contentSize大小相同。

I made a subclass of UICollectionView , implemented intrinsicContentSize method, and set the UICollectionView 's class to my custom class in IB. 我创建了UICollectionView的子类,实现了intrinsicContentSize方法,并将UICollectionView的类设置为IB中的自定义类。 However intrinsicContentSize never gets called. 然而, intrinsicContentSize永远不会被调用。 I have the exact same setup with an UITableView and there it works flawlessly. 我有一个与UITableView完全相同的设置,它在那里完美无缺。

Any ideas on this? 有什么想法吗?

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

The correct answer is to do something like this 正确的答案是做这样的事情

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

And call -invalidateContentSize whenever you think it needs to change (after reloadData for example). 每当您认为需要更改时调用-invalidateContentSize(例如在reloadData之后)。

In Interface Builder you may need to set placeholder intrinsic size constraints to avoid errors. 在Interface Builder中,您可能需要设置占位符内在大小约束以避免错误。

This is subclassing and overriding of -intrinsicContentSize useful if you want to grow a collection view's frame until it is constrained by a sibling or parent view 这是-intrinsicContentSize的子类化和重写,如果你想增长一个集合视图的框架,直到它被一个兄弟或父视图约束

I'm not sure why it's happening. 我不确定为什么会这样。 Here's another solution to this problem. 这是此问题的另一种解决方案。 Set up a height constraint on UICollectionView object. UICollectionView对象上设置高度约束。 Then set its constant to be equal to self.collectionView.contentSize.height . 然后将其constant设置为等于self.collectionView.contentSize.height I use a similar approach in my app, though I've got UITextView instead of UICollectionView . 我在我的应用程序中使用了类似的方法,虽然我有UITextView而不是UICollectionView

UPDATE: I've found a way to do this with intrinsicContentSize : UITextView in UIScrollView using auto layout 更新:我已经找到了使用intrinsicContentSizeUIScrollView中的UITextView使用自动布局

Use this class to make UICollectionView update its intrinsic content size every time the content is changed. 每次更改内容时,使用此类使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()
        }
    }
}

Though, you should understand that if you embed it into another scroll view, cell recycling will not work. 但是,您应该明白,如果将其嵌入到另一个滚动视图中,则单元格回收将不起作用。 The most appreciated way to deal with nested collection view is described here . 处理嵌套集合视图最欣赏的方式描述了这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM