使用自定义 UITableViewCell 自动布局,无需以编程方式编写故事板 (Swift 5)

Auto layout with custom UITableViewCell without storyboard programmatically (Swift 5)

我在 UITableViewCell 范围内使用自动布局时遇到了一些困难。我是 Swift 的新手,因此我们将不胜感激。我正在尝试创建一个自定义单元格,其中单元格包含如图所示排列的三个 UIImageView 对象。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  +----------------------------------+   +-----------------------------------+
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |               view2               |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   +-----------------------------------+
  |               view1              |
  |                                  |   +-----------------------------------+
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |               view3               |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  +----------------------------------+   +-----------------------------------+
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

但我实际得到的是以下视图,其中 view1、view2 和 view3 已正确对齐,但它们没有锚定到底部单元格的 contentView,因为它是一个可调整大小的单元格,没有固定任何内容在底部,它会忽略内容并将自身固定为估计的 44 高估计单元格高度。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  +----------------------------------+   +-----------------------------------+
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  |                                  |   |               view2               |
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  |                                  |   +-----------------------------------+
  |               view1              |
  |                                  |   +-----------------------------------+
  |                                  |   |                                   |
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |               view3               |
  |                                  |   |                                   |
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  |                                  |   |                                   |
  |                                  |   |                                   |
  |                                  |   |                                   |
  +----------------------------------+   +-----------------------------------+
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

下面的代码包含一个 .anchor 方法作为 UIView 扩展,用于更有效地处理锚点,否则您就明白了。

import UIKit

class GalleryTableCell: UITableViewCell, SelfConfiguringCell {

    lazy var view1: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var view2: UIView = {
        let view = UIView()
        view.backgroundColor = .blue
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var view3: UIView = {
        let view = UIView()
        view.backgroundColor = .green
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    static var identifier: String {
        return String(describing: self)
    }

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupCellView()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupCellView() {
        backgroundColor = .systemBackground
        [view1, view2, view3].forEach { ( addSubview([=13=]) ) }

        view1.anchor(top: topAnchor, bottom: nil, leading: nil, trailing: trailingAnchor, with: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 6), size: CGSize(width: 175, height: 0))

        view1.heightAnchor.constraint(equalTo: view1.widthAnchor).isActive = true

        view2.anchor(top: view1.bottomAnchor, bottom: nil, leading: nil, trailing: view1.trailingAnchor, with: UIEdgeInsets(top: 6, left: 0, bottom: 0, right: 0))
        view2.resize(to: view1)

        view3.anchor(top: topAnchor, bottom: view2.bottomAnchor, leading: leadingAnchor, trailing: view1.leadingAnchor, with: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 6))

    }

    func configure(with app: Any) {}

}

因为我使用自动尺寸来自动调整单元格的大小,所以需要上面的行来将视图限制在单元格中,否则单元格的大小将调整为估计的高度 (44),并且三个视图将扩展覆盖在它下面的多个单元格上。

帮助理解我做错了什么将不胜感激。

要获得自动调整大小,您需要做 3 件事:

  1. estimatedRowHeight 设置为您认为的任何大小。它不一定是精确的,但它有助于提高性能。
  2. rowHeight 设置为 UITableView.automaticDimension
  3. 设置 viewtop & bottom 约束以及 height 约束。