首页 > 解决方案 > 自定尺寸表视图单元内的自定尺寸表视图

问题描述

假设我有这样的层次结构:

*TableViewCell
**TableView
***TableViewCell

并且所有这些都应该是可调整大小的。有人遇到过这种问题吗?在过去,我使用了许多解决方法,例如systemLayoutSizeFitting或预先计算高度 in heightForRowAt,但它总是打破一些约束,因为TableViewCell高度约束等于估计的行高,并且出现了一些神奇的行为。有什么方法可以让它活起来吗?

当前解决方法:

class SportCenterReviewsTableCell: UITableViewCell, MVVMView {
    var tableView: SelfSizedTableView = {
        let view = SelfSizedTableView(frame: .zero)
        view.clipsToBounds = true
        view.tableFooterView = UIView()
        view.separatorStyle = .none
        view.isScrollEnabled = false
        view.showsVerticalScrollIndicator = false
        view.estimatedRowHeight = 0
        if #available(iOS 11.0, *) {
            view.contentInsetAdjustmentBehavior = .never
        } else {
            // Fallback on earlier versions
        }

        return view
    }()

    private func markup() {
        contentView.addSubview(tableView)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(ReviewsTableViewCell.self, forCellReuseIdentifier: "Cell")
        tableView.snp.makeConstraints() { make in
            make.top.equalTo(seeAllButton.snp.bottom).offset(12)
            make.left.equalTo(contentView.snp.left)
            make.right.equalTo(contentView.snp.right)
            make.bottom.lessThanOrEqualTo(contentView.snp.bottom)
        }
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ReviewsTableViewCell

        cell.viewModel = viewModel.cellViewModels[indexPath.row]

        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! ReviewsTableViewCell

        cell.viewModel = viewModel.cellViewModels[indexPath.row]
        cell.setNeedsLayout()
        cell.layoutIfNeeded()
        let size = cell.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize, withHorizontalFittingPriority: .defaultHigh, verticalFittingPriority: .defaultLow)

        return size.height
    }
}

自定尺寸 tableView 类:

class SelfSizedTableView: UITableView {
    override func reloadData() {
        super.reloadData()
        self.invalidateIntrinsicContentSize()
        self.layoutIfNeeded()
    }

    override var intrinsicContentSize: CGSize {
        self.setNeedsLayout()
        self.layoutIfNeeded()
        return contentSize
    }
}

标签: iosswiftuitableviewuitableviewautomaticdimension

解决方案


这实际上不是问题的答案,而只是一个解释。
(写在这里是因为评论的字符数限制)。

问题是你试图在另一个垂直滚动视图中插入一个垂直滚动视图。如果不禁用嵌套 tableview 的滚动功能,滚动时会出现故障,因为系统不知道将滚动事件传递给谁(嵌套 tableview 或父 tableview)。因此,在我们的例子中,您必须禁用嵌套表格视图的“可滚动”属性,因此您必须将嵌套表格视图的高度设置为等于其内容大小。但是这样你就会失去 tableview 的优势(即单元格重用优势),它与使用实际的 UIScrollView 相同。但是,另一方面,由于您必须将高度设置为等于其内容大小,所以根本没有理由使用 UIScrollView,

*TableView
**TableViewCell
***StackView
****Items
****Items
****Items
****Items

但同样,正确的解决方案是使用多部分表格视图。让你的单元格成为表格视图的部分标题,让内部单元格成为表格视图的行。


推荐阅读