【问题标题】:collectionViewContentSize in iOS 10 using self-sizing cellsiOS 10 中的 collectionViewContentSize 使用自调整单元格
【发布时间】:2017-01-22 17:39:33
【问题描述】:

在 iOS 10 之前,我有一个自调整大小的表格视图,它仅由一个 UICollectionView 和使用标准 UICollectionViewFlowLayout 的自调整单元格组成。集合视图单元格使用自动布局调整大小。为了让表格单元格正确调整大小,我必须找到集合视图的内容大小并在表格单元格的 systemLayoutSizeFittingSize:withHorizo​​ntalFittingPriority:verticalFittingPriority: 中使用它。

我还发现对 collectionView.collectionViewLayout.collectionViewContentSize 的调用使用了估计的ItemSize 而不是正确大小的单元格大小,除非我调用了 collectionView layoutIfNeeded。这导致 systemLayoutSizeFittingSize 为:

- (CGSize) systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority
{
    self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX);
    [self.collectionView layoutIfNeeded];

    CGSize collectionViewContentSize = self.collectionView.collectionViewLayout.collectionViewContentSize;
    CGFloat verticalPadding = fabs(self.collectionViewTopPaddingConstraint.constant) + fabs(self.collectionViewBottomPaddingConstraint.constant);
    CGSize cellSize = CGSizeMake(collectionViewContentSize.width, collectionViewContentSize.height + verticalPadding);

    return cellSize;
}

现在对 layoutIfNeeded 的调用会导致 *** Assertion failure in -[_UIFlowLayoutSection computeLayoutInRect:forSection:invalidating:invalidationContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/UIFlowLayoutSupport.m:823

我在 systemLayoutSizeFittingSize 中调用 layoutIfNeeded 是否违反了某些道德规则?当使用自调整单元格时,是否有更好的方法来计算集合视图的内容大小?我宁愿不必从自动布局转移到在代码中进行这些大小计算,但这肯定是最坏的情况。

【问题讨论】:

    标签: ios objective-c uicollectionview ios10


    【解决方案1】:

    这是 iOS10 中的一些奇怪错误,仅适用于 iPhone Plus 设备。我遇到了同样的问题,我的解决方案是像这样调用layoutIfNeeded

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        collectionView.layoutIfNeeded() // Patch: only to solve UIKit crash on Plus models
        return 1
    }
    

    在不同的 UICollectionViewDataSources 方法中做同样的事情也会起作用

    【讨论】:

    • 天哪,我本来是head() -> Desk。我不想知道你是怎么偶然发现这个的。
    • 我遇到过的最奇怪的错误,我疯狂地崩溃了...
    • @user924 正如我所说“在不同的 UICollectionViewDataSources 方法中做同样的事情也可以”试试吧。
    【解决方案2】:

    我在 iOS 10 上开发我的应用时遇到了同样的问题。删除第一行解决了我的问题。

    self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX); //Remove this

    希望对您有所帮助!

    【讨论】:

    • 如果没有将框架设置为合适的宽度,就会导致布局尺寸计算错误。它不会崩溃,但大小完全错误。我最终用自定义网格 UIView 子类替换了我的集合视图,因为布局计算相对简单,并且自调整大小的集合视图介于脆弱和不可用之间。
    • 你尝试打电话给[self.collectionView.superView layoutIfNeeded];
    • 这会导致集合视图中的不同断言失败。
    【解决方案3】:

    就我而言,在布局之前调用invalidateLayout 是解决此问题的一种解决方法。

    UIViewController 子类中:

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        collectionView.collectionViewLayout.invalidateLayout()
    }
    

    或在UIView 子类中:

    override func layoutSubviews() {
        super.layoutSubviews()
        collectionView.collectionViewLayout.invalidateLayout()
    }
    

    【讨论】:

    • 这会导致布局反馈循环
    【解决方案4】:

    在 iOS 10 上开发我的应用并在 awakeFromNib 上将 UICollectionViewDataSource 设置为自身时遇到了同样的问题,如下所示:

    override func awakeFromNib() {
        super.awakeFromNib()
        let layout = UICollectionViewFlowLayout()
        // set your layout 
        collectionViewLayout = layout
        // set dataSource equal to self in here cause a crash
        dataSource = self
    }
    

    然后我把UICollectionViewDataSource的设置代码移到layoutSubviews,问题就解决了,像这样:

    override func layoutSubviews() {
            super.layoutSubviews()
            dataSource = self
        }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        let layout = UICollectionViewFlowLayout()
        // set your layout 
        collectionViewLayout = layout
        // set dataSource equal to self in here cause a crash
        dataSource = self
    }
    

    希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多