ios - 自定尺寸表视图单元内的自定尺寸表视图
问题描述
假设我有这样的层次结构:
*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
}
}
解决方案
这实际上不是问题的答案,而只是一个解释。
(写在这里是因为评论的字符数限制)。
问题是你试图在另一个垂直滚动视图中插入一个垂直滚动视图。如果不禁用嵌套 tableview 的滚动功能,滚动时会出现故障,因为系统不知道将滚动事件传递给谁(嵌套 tableview 或父 tableview)。因此,在我们的例子中,您必须禁用嵌套表格视图的“可滚动”属性,因此您必须将嵌套表格视图的高度设置为等于其内容大小。但是这样你就会失去 tableview 的优势(即单元格重用优势),它与使用实际的 UIScrollView 相同。但是,另一方面,由于您必须将高度设置为等于其内容大小,所以根本没有理由使用 UIScrollView,
*TableView
**TableViewCell
***StackView
****Items
****Items
****Items
****Items
但同样,正确的解决方案是使用多部分表格视图。让你的单元格成为表格视图的部分标题,让内部单元格成为表格视图的行。
推荐阅读
- javascript - 如何在具有多个下拉列表的javascript中使用if else语句?
- java - 调用函数时模拟器抛出异常(android studio)
- javascript - 如何为 JEE 或 NEET 等测验制作带有 2 个选项的提交按钮 根据选择显示问题
- reactjs - webpack-built bundle 中的 React 注释包含代码并使供应商块太大
- wordpress - Wordpress 多站点更改新的子站点管理员用户角色
- python - 在 pandas 数据帧上使用 for 循环生成唯一语句
- node.js - 使用sails js显示和下载PDF文件的问题
- angular - 在角度应用程序中向上而不是向下加载更多按钮推送元素
- python - 值大于范围 [-2,256] 的整数对象具有相同的“id”
- jquery - 如何在 Vue.js 3 / Vite 应用程序中将 jQuery 导入 $