【问题标题】:UICollectionView not calling intrinsicContentSizeUICollectionView 不调用intrinsicContentSize
【发布时间】:2013-10-22 00:32:33
【问题描述】:

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

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

对此有何想法?

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

【问题讨论】:

  • 您在 IB 中设置了任何限制条件吗?

标签: ios uicollectionview autolayout uicollectionviewlayout


【解决方案1】:

正确的答案是这样做

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

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

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

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

【讨论】:

    【解决方案2】:

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

    更新:我找到了一种方法来使用intrinsicContentSizeUITextView in UIScrollView using auto layout

    【讨论】:

    • 这就是我现在使用的解决方法。但无论如何,我认为这将是使用intrinsicContentSize 的一种“更清洁”的方式。如果有人有想法,我会等待,否则我会接受你的回答。
    • @BenLime:我刚刚让它在我的项目中工作。当您将 IB 中的内在大小设置为 Placeholder: dl.dropboxusercontent.com/u/5184129/Screenshots/4p0p.png 时,您能看到会发生什么吗?
    • 还是没有运气。在一个额外的项目中尝试了Placeholder 的东西,但我遇到了同样的行为。你还做了什么?
    • github.com/fastred/UICollectionView-intrinsicContentSize 我是这样做的。 intrinsicContentSize: 不会在轮换时调用,因此最终这样做可能是错误的方式。
    • 谢谢。我想我会遵守上面提到的高度限制。
    【解决方案3】:

    使用这个类让 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 2013-06-26
      • 1970-01-01
      • 2017-08-24
      相关资源
      最近更新 更多