首页 > 解决方案 > 如何使用自动调整其高度的 SnapKit 以编程方式创建 UITableViewCell?

问题描述

看似简单的事情,结果却是非常困难。我已经在这里和 SnapKit GitHub 上浏览了多个主题,但未能解决我的问题。

我想有UITableViewCell一个位于中间的标签,比如说从单元格的顶部和底部都 50。

值得一提的是,单元格是以编程方式创建的

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    self.addSubview(titleLabel)
    titleLabel.snp.makeConstraints { (make) -> Void in
        make.topMargin.equalToSuperview().offset(50.0)
        make.left.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue:10.0))
        make.bottomMargin.equalToSuperview().offset(50.0)

    }
}

在 ViewController 中,我尝试了两种自动单元格高度的方法:

 extension EpisodeViewController: UITableViewDelegate {
  func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
  }
}

tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension

viewDidLoad()方法中

我得到的是:

在此处输入图像描述

这三个单元格中的每一个都应填充“测试” - 相反,它已将标签向下推到相应单元格下方,而无需调整单元格的大小。

尝试了许多不同的组合,例如:

1) 将约束优先级设置为 999 - 无变化

2)添加到 contentView 而不是 self - 根本不显示

3) 使用 top 而不是 topMargin 等 - 没有区别

你能告诉我这段代码有什么问题吗?在以编程方式创建的单元格中使用 SnapKit 时的一般经验法则是什么?应该根据约束自动调整其高度?

提前致谢

编辑

UITableView数据源方法

extension EpisodeViewController: UITableViewDataSource {

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: EpisodeHeaderCell = tableView.dequeueReusableCell(for: indexPath)
    cell.viewModel = viewModel
    return cell
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

}

标签: iosswiftuitableviewautolayoutsnapkit

解决方案


    label.snp.makeConstraints {
        $0.left.equalToSuperview().offset(10)
        $0.right.equalToSuperview().offset(-10)
        $0.top.equalToSuperview().offset(50)
        $0.bottom.equalToSuperview().offset(-50)
    }

这是 viewController.swift 文件的完整代码。

class TestCell: UITableViewCell {
    static let identifier: String = "test_cell_identifier"

    var label: UILabel!

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

    func configure() {
        label = UILabel(frame: .zero)
        self.contentView.addSubview(label)
        label.snp.makeConstraints {
            $0.left.equalToSuperview().offset(10)
            $0.right.equalToSuperview().offset(-10)
            $0.top.equalToSuperview().offset(50)
            $0.bottom.equalToSuperview().offset(-50)
        }
    }

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

class ViewController: UIViewController {
    var data: [String] = [
        "Test1",
        "Test2",
        "Test3"
    ]

    var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView = UITableView(frame: .zero)
        self.view.addSubview(tableView)
        tableView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
        tableView.register(TestCell.self, forCellReuseIdentifier: TestCell.identifier)
        tableView.dataSource = self
        tableView.delegate = self

        tableView.estimatedRowHeight = 100
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: TestCell.identifier, for: indexPath) as! TestCell
        cell.label.text = data[indexPath.item]
        return cell
    }
}

推荐阅读