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

UICollectionViewCell:自动布局-大小计算不正确(偏移10磅)

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

    我有一套 UICollectionViewCell 具有不同布局的子类(使用AutoLayout)。

    由于“自调整单元格大小”功能已完全中断,因此我在 数据来源 正好是10磅 小于它应该是,不管细胞。

    下面是我用来计算尺寸的代码:

      let sizeCache = CellCache() // Size cache stores previously calculated values
      func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if let cachedSize = sizeCache.sizeAtIndexPath(indexPath: indexPath) {
          return cachedSize // Return cached value if it exists
        }
    
        // Calculate the size if not found in the cache
        let cellClass = cellTypeAt(indexPath: indexPath) // Get the class type
        let cell = sizeCache.createCellOfTypeIfNeeded(cellType: cellClass) // Dequeue or instantiate a cell
        self.collectionView(collectionView, cell: cell, configureAt: indexPath) // Ask DataSource to configure this cell
        let fittingSize = CGSize(width: collectionView.bounds.width - 16, height: 0) // Set the padding to 16
        cell.bounds = CGRect(origin: .zero, size: fittingSize) // Set cell's width
        var result = cell.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) // Calculate cell's size using AutoLayout
        result.width = collectionView.bounds.width - 16 // Set the padding
        result.height = result.height + 10 // !!! Error - Add 10 pt to the result !!!
        sizeCache.setSize(size: result, at: indexPath) // Cache the result
        return result
      }
    

    注意结尾的那行 让它工作。

    width 约束条件:

    import UIKit
    import SnapKit
    
    class AutoSizingCellBase: UICollectionViewCell {
      override class var requiresConstraintBasedLayout: Bool {
        return true
      }
    
      private final 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()
      }
    }
    

    问题的例子:

    正确尺寸(添加10磅后) Correct sizing (after adding 10 pt

    尺寸不正确(未添加10磅) Incorrect sizing (without adding 10 pt)

    这个问题影响到所有的细胞。根本原因是什么?

    更新:约束示例 以下是我用于配置所示视图的约束:

      private func setupConstraints() {
        price.setContentCompressionResistancePriority(.required, for: .horizontal)
        disclosureIndicator.setContentCompressionResistancePriority(.required, for: .horizontal)
        disclosureIndicator.setContentCompressionResistancePriority(.required, for: .vertical)
        disclosureIndicator.setContentHuggingPriority(.required, for: .horizontal)
        disclosureIndicator.setContentHuggingPriority(.required, for: .vertical)
    
        title.snp.makeConstraints { (make) in
          make.leading.top.equalTo(contentView.layoutMarginsGuide)
          make.trailing.lessThanOrEqualTo(price.snp.leading).offset(-8)
        }
    
        subtitle.snp.makeConstraints { (make) in
          make.top.equalTo(title.snp.bottom).offset(8)
          make.leading.bottom.equalTo(contentView.layoutMarginsGuide)
        }
    
        disclosureIndicator.snp.makeConstraints { (make) in
          make.trailing.equalTo(contentView.layoutMarginsGuide)
          make.centerY.equalToSuperview()
        }
    
        price.snp.makeConstraints { (make) in
          make.trailing.equalTo(disclosureIndicator.snp.leading).offset(-8)
          make.centerY.equalToSuperview()
        }
      }
    

    这是一个相当复杂的例子,但即使使用更简单的例子,问题也是可以重现的:

      private func setupConstraints() {
        button.snp.makeConstraints { (make) in
          make.width.equalToSuperview() // Button is a subview of the UIStackView
        }
    
        stack.snp.makeConstraints { (make) in
          make.edges.equalTo(contentView.layoutMarginsGuide)
          make.height.greaterThanOrEqualTo(150)
        }
      }
    

    在约束中添加偏移可以解决问题,而视图层次调试器仍然显示“不明确的布局”:

    subtitle.snp.makeConstraints { (make) in
      make.top.equalTo(title.snp.bottom).offset(8)
      make.leading.equalTo(contentView.layoutMarginsGuide)
      make.bottom.equalTo(contentView.layoutMarginsGuide).offset(-10) // Subtracted 10
    }
    

    问题是,在哪里 10 是从什么地方来的,现在还开着。

    更新3 layoutMargins :

    UIView.appearance().layoutMargins = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
    

    AppDelegate ,大小计算变得正确,尽管单元格的外观发生了变化。 UICollectionView .

    Cells without insets

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

    LayoutMargins UICollectionViewCell 添加到superview和不在视图层次结构中时。

    UIView.appearance().layoutMargins = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
    

    推荐文章