代码之家  ›  专栏  ›  技术社区  ›  Richard Topchii

AutoSizingCells PreferredLayoutAttributes适合性能[WWDC 2018]

  •  4
  • Richard Topchii  · 技术社区  · 7 年前

    我正在使用uiCollectionView自动调整单元格大小,它看起来类似于uiTableView。

    如前几个问题所述: q1 , q2 采用自定尺寸单元需要实施 preferredLayoutAttributesFitting(_:) 方法使用 systemLayoutSizeFitting(_ targetSize:) .

    但是,在最近的WWDC会话中( High Performance Auto Layout 有人提到,使用 SystemLayoutSize设置(\uTargetSize:) 代价高昂,因为它会创建一个新的自动布局引擎,然后将其丢弃,要求它解决所有约束,而不缓存以前计算的结果。

    在我的应用程序中,我以答案中建议的方式实现了自我调整大小。但是,在类似于表的列表(许多行的高度很小)中,滚动性能非常糟糕。

    显然,打电话 SystemLayoutSize设置(\uTargetSize:) 在一个 UICollectionViewCell 仅仅计算它的大小是昂贵的,而且要耗费cpu(因为大小估计和实际布局都发生在主线程上)。

    同时达到以下结果的建议方法是什么

    1. 无暂停滚动uicollectionview
    2. 使单元格的宽度固定并等于 UICollectionView Width minus margins ?

    推荐的策略是什么,自动调整单元格大小和高滚动性能?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Richard Topchii    7 年前

    通过向基类添加宽度约束而修复。自从 preferredLayoutAttributesFitting 方法仅用于更新首选宽度。

    这个 updateConstraints 在收集滚动期间,不会每次调用方法,这样可以防止约束的变化:

    import UIKit
    import SnapKit
    
    class AutoSizingCellBase: UICollectionViewCell {
      override class var requiresConstraintBasedLayout: Bool {
        return true
      }
    
      private var widthConstraint: Constraint?
    
      override func updateConstraints() {
        if widthConstraint == nil {
          if let window = window {
            let width = window.bounds.width - 16
            contentView.snp.makeConstraints { (make) in
              widthConstraint = make.width.equalTo(width).constraint
            }
          }
        }
        super.updateConstraints()
      }
    }
    

    此外,还可以将单元格约束到 superview 自从 更新约束 方法在将视图添加到层次结构后调用。