【问题标题】:How to dynamically resize custom UITableViewCells in UITableView?如何在 UITableView 中动态调整自定义 UITableViewCells 的大小?
【发布时间】:2021-09-18 17:22:03
【问题描述】:

我构建了一个通用的UITableView,我可以将模型和自定义的UITableViewCell 传递给它,它运行良好,除了两件事:单元格高度和UITableView 高度。

我猜这两个问题是相关的。

我正在尝试我在 SO 上找到的多种方法来帮助解决它,但没有任何结果。

这是我的通用 UITableView 的示例:

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.register(Cell.self, forCellReuseIdentifier: "Cell")

    tableView.dataSource = self
    tableView.delegate = self
    tableView.separatorStyle = .none

    loadList(appendItems: true)

    initActions()
    initLayout()
}

func initLayout() {
    self.view.addSubview(tableView)
    self.view.addSubview(emptyView)
    self.view.addSubview(loadMoreButton)

    tableView.translatesAutoresizingMaskIntoConstraints = false
    tableView.snp.makeConstraints { (make) -> Void in
        make.left.right.leading.trailing.top.equalToSuperview()
    }
    tableView.isScrollEnabled = false

    emptyView.translatesAutoresizingMaskIntoConstraints = false
    emptyView.isHidden = true
    emptyView.textAlignment = .center
    emptyView.snp.makeConstraints { (make) -> Void in
        make.left.right.leading.trailing.equalToSuperview()
        make.top.equalToSuperview().offset(8)
    }

    self.loadMoreButton.isHidden = true
    if(self.hasLoader == true) {
        self.loadMoreButton.isHidden = false
        loadMoreButton.translatesAutoresizingMaskIntoConstraints = false
        loadMoreButton.snp.makeConstraints { (make) -> Void in
            make.centerX.equalToSuperview()
            make.top.equalTo(tableView.snp.bottom)
        }
    }
}

然后,当我的数据被加载时,我会这样做:

self.tableView.reloadData()
self.tableView.snp.remakeConstraints { (make) -> Void in
    make.left.right.leading.trailing.top.equalToSuperview()
    if(self.hasLoader == true) {
        make.bottom.equalTo(self.loadMoreButton.snp.top)
    }
    make.height.equalTo(self.tableView.contentSize.height)
}

那么,我的tableView funcs:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return resourceList.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
    let currentResource = resourceList[indexPath.row]
    cell.setResource(resource: currentResource) // Here I initialize my labels, UIImage, etc.
    cell.isUserInteractionEnabled = true
    self.cellHeight = cell.contentView.frame.size.height // Something I tried
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.tableView.deselectRow(at: indexPath, animated: true)
    let resource = resourceList[indexPath.row]
    if (resource.getRouteParam() != "") {
        router.setRoute(routeName: resource.getRouteName(), routeParam: resource.getRouteParam())
    }
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return self.cellHeight ?? 200 // Here I'm trying to return an *automatic* height of my custom cell
}

为了完成,我可以说我的单元格由于标签长度不同而具有不同的大小,因此我无法定义静态高度。

我也尝试在我的viewDidLoad 方法中添加estimatedHeightForRowAt,但它也不起作用。

当我使用 UITableView.automaticDimension 时,我的单元格的高度始终为 44.0

【问题讨论】:

    标签: ios swift uitableview


    【解决方案1】:

    1。 UITableView配置

    为了能够在UITableView 中自动调整单元格大小,您需要在表格视图中设置以下属性:

    tableView.rowHeight = UITableView.automaticDimension
    tableView.estimatedRowHeight = 200 // or other value
    

    2。 UITableViewCell 内部的正确自动布局

    确保您的单元格中正确设置了自动布局。

    3。 (可选)UITableViewDelegateestimatedHeightForRowAt

    实现UITableViewDelegate这个方法,为表格提供更准确的尺寸,从而正确处理快速滚动。

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 200 // try to calculate more accurate size
    }
    

    我注意到的一些东西

    1. 这不会像您期望的那样真正起作用,所以不要打扰它。这里的单元格视图甚至没有正确布局,因此您很有可能会得到有问题的值(例如 0)
    self.cellHeight = cell.contentView.frame.size.height
    
    1. 重新加载数据后应该不需要重新设置约束。在 viewDidLoad 中设置它们就足够了。
    self.tableView.reloadData()
    self.tableView.snp.remakeConstraints
    

    资源

    How to make UITableViewCells auto resize to their content

    Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

    【讨论】:

    • 我认为estimatedHeightForRowAt它也需要返回UITableView.automaticDimension
    • 根本不需要实现estimatedHeightForRowAt,但如果你这样做了,你应该返回你根据单元格内容或单元格类型或其他适合你的情况的参数估计的值。文档指出:“如果您没有估算值,请返回 automaticDimension。”
    • 我成功地将 UITableViewCells 设置为正确的高度:问题在于在我的单元格内进行了正确的设置。现在我的 UITableView 高度没有设置为适合 contentSize。
    • 你的意思是UITableView height != UITableView.contentSize.height?这不是表格视图的工作方式,它的内容大小(高度)将独立于表格视图自身的大小。它的内容大小由单元格的数量及其大小定义
    猜你喜欢
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多