SwiftUI中嵌入自定义UITableView不加载,cellForRow方法未执行
问题:SwiftUI中嵌入UIKit自定义TableView不显示内容
场景:需在SwiftUI中使用带TableView的UIKit自定义视图,TableView无内容显示,但除cellForRowAt外其他代理方法正常执行,项目未使用Storyboard。
问题根源
CustomTableView中的tableView是计算属性,每次访问都会创建新的MyCustomTableView实例,且从未将其添加到CustomTableView的视图层级中,导致TableView根本不会被渲染。updateUIView中调用uiView.tableView.reloadData()时,又会生成新的TableView实例,reload操作完全作用在未显示的新实例上,无效。
修复方案
1. 重构CustomTableView,将tableView改为存储属性并添加到视图层级
修改后的CustomTableView代码:
class CustomTableView: UIView, UITableViewDelegate, UITableViewDataSource { // 将计算属性改为存储属性 let tableView = MyCustomTableView(frame: .zero, style: .plain) override init(frame: CGRect) { super.init(frame: frame) setupTableView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupTableView() { tableView.delegate = self tableView.dataSource = self // 将tableView添加到当前视图 addSubview(tableView) // 设置自动布局,让tableView填充整个CustomTableView tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: topAnchor), tableView.leadingAnchor.constraint(equalTo: leadingAnchor), tableView.trailingAnchor.constraint(equalTo: trailingAnchor), tableView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .default, reuseIdentifier: nil) cell.textLabel?.text = "Hello \(indexPath.row)" return cell } }
2. 调整CustomTableViewRepresentable的update逻辑
无需每次生成新TableView,直接调用已存在的tableView实例的reloadData:
struct CustomTableViewRepresentable: UIViewRepresentable { func makeUIView(context: Context) -> CustomTableView { CustomTableView(frame: .zero) } func updateUIView(_ uiView: CustomTableView, context: Context) { // 调用已添加到视图层级的tableView实例 uiView.tableView.reloadData() } }
3. (可选)优化TableViewCell的复用(推荐)
如果后续需要自定义Cell,建议提前注册复用标识符,避免重复创建Cell:
在setupTableView中添加:
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DefaultCell")
然后修改cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultCell", for: indexPath) cell.textLabel?.text = "Hello \(indexPath.row)" return cell }
验证
修改后,SwiftUI视图中的TableView会正常显示10行"Hello X"的内容,所有代理方法均能正常触发。
内容的提问来源于stack exchange,提问作者HVN
相关产品推荐
相关产品推荐

