自调整tableview单元内的自调整tableview [英] Self sizing tableview inside self sizing tableview cell

查看:82
本文介绍了自调整tableview单元内的自调整tableview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say I have hierarchy like this:

*TableViewCell
**TableView
***TableViewCell

,所有这些都应调整大小.有人遇到过这种问题吗?过去,我曾使用过许多变通方法,例如 systemLayoutSizeFitting heightForRowAt 中的高度预计算,但是由于 TableViewCell 具有高度限制,它总是会打破一些约束.等于估计的行高,并且会出现某种魔术行为.有什么方法可以使它变得生动起来吗?

and all of them should be resizable. Did someone face this kind of problem? In past I've used many workarounds like systemLayoutSizeFitting or precalculation of height in heightForRowAt, but it always breaks some constraints, because TableViewCell has height constraint equal to estimated row height and there appear some kinds of magic behavior. Any ways to make this live?

当前解决方法:

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类:

Self sizing tableView class:

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

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

推荐答案

这实际上不是对问题的答案,而只是一个解释.
(由于注释的字符数限制,在此写上.)

This is actually not an answer to the question, but just an explanation.
(Wrote here because of the character count limitation for the comments).

问题是您试图在另一个垂直滚动视图内插入一个垂直滚动视图.如果不禁用嵌套表视图的滚动功能,则滚动时会出现故障,因为系统将不知道向谁传递滚动事件(嵌套表视图或父表视图).因此,在本例中,您必须为嵌套表视图禁用"scrollable"属性,因此必须将嵌套表视图的高度设置为等于其内容大小.但是这样一来,您将失去tableview的优势(即单元重用优势),并且与使用实际的UIScrollView相同.但是,另一方面,由于必须将高度设置为等于其内容大小,因此根本没有理由使用UIScrollView,可以将嵌套的单元格添加到UIStackView中,并且tableview将具有此层次结构:

The thing is that you're trying to insert a vertically scrollable view inside another vertically scrollable view. If you don't disable the nested tableview's scroll ability, you will have a glitch while scrolling, because the system wouldn't know to whom pass the scroll event (to the nested tableview, or to the parent tableview). So in our case, you'll have to disable the "scrollable" property for the nested tableviews, hence you'll have to set the height of the nested tableview to be equal to its content size. But this way you will lose the advantages of tableview (i.e. cell reusing advantage) and it will be the same as using an actual UIScrollView. But, on the other hand, as you'll have to set the height to be equal to its content size, then there is no reason to use UIScrollView at all, you can add your nested cells to a UIStackView, and you tableview will have this hierarchy:

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


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


But again, the right solution is using multi-sectional tableview. Let your cells be section headers of the tableview, and let inner cells be the rows of the tableview.

这篇关于自调整tableview单元内的自调整tableview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆