iOS新手求助:动态控制UITableView高度及空数据时完全隐藏视图
嘿,我来帮你一步步搞定这个需求!作为iOS新手,用StackView来管理布局会让你省超多事,结合动态高度控制和空数据移除的逻辑,完全能实现你要的效果。
第一步:用UIStackView简化布局(重点!)
先在Storyboard里做个省心的布局:
- 把你需要的所有视图(ImageView、Button、Labels、两个TableView)都放进一个垂直方向的UIStackView里
- 设置StackView的核心属性:
- Axis: Vertical(垂直排列)
- Spacing: 16(或者你想要的间距)
- Alignment: Fill(子视图填满宽度)
- Distribution: Fill(根据内容自动分配空间)
- 给StackView加约束:比如leading、trailing、top、bottom都贴到父视图的Safe Area,让它自适应屏幕
- 给每个TableView拖出高度约束的IBOutlet(比如
tableView1HeightConstraint、tableView2HeightConstraint),同时给TableView设置rowHeight = UITableView.automaticDimension、estimatedRowHeight = 100(让动态Cell能自动计算高度)
第二步:代码基础准备
先把必要的IBOutlet和数据源定义好:
import UIKit class YourViewController: UIViewController { // 主StackView的IBOutlet @IBOutlet weak var mainStackView: UIStackView! // 两个TableView的IBOutlet @IBOutlet weak var tableView1: UITableView! @IBOutlet weak var tableView2: UITableView! // 两个TableView的高度约束IBOutlet @IBOutlet weak var tableView1HeightConstraint: NSLayoutConstraint! @IBOutlet weak var tableView2HeightConstraint: NSLayoutConstraint! // 数据源数组 private var dataSource1: [YourDataModel] = [] private var dataSource2: [YourDataModel] = [] override func viewDidLoad() { super.viewDidLoad() // 配置TableView的动态Cell高度 tableView1.rowHeight = UITableView.automaticDimension tableView1.estimatedRowHeight = 100 tableView2.rowHeight = UITableView.automaticDimension tableView2.estimatedRowHeight = 100 // 注册自定义Cell(如果用了自定义Cell的话) tableView1.register(UINib(nibName: "YourCustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellID") tableView2.register(UINib(nibName: "YourCustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellID") // 设置数据源和代理 tableView1.dataSource = self tableView2.dataSource = self // 发起API请求 fetchDataFromAPI() } } // MARK: - UITableView数据源实现 extension YourViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tableView == tableView1 ? dataSource1.count : dataSource2.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCellID", for: indexPath) as! YourCustomCell let data = tableView == tableView1 ? dataSource1[indexPath.row] : dataSource2[indexPath.row] // 配置Cell内容,比如: cell.titleLabel.text = data.title cell.subtitleLabel.text = data.subtitle return cell } }
第三步:动态调整TableView高度
写个通用方法,两个TableView都能复用:
private func updateTableViewHeight(_ tableView: UITableView, heightConstraint: NSLayoutConstraint) { tableView.reloadData() // 强制TableView完成布局,确保contentSize计算准确 tableView.layoutIfNeeded() // 把高度约束设为TableView内容的实际高度 heightConstraint.constant = tableView.contentSize.height // 加个动画,过渡更自然 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } }
第四步:根据API数据控制显示/移除TableView
核心逻辑:数据为空就从StackView里移除,有数据就加回去并调整高度:
private func handleTableViewVisibility(tableView: UITableView, heightConstraint: NSLayoutConstraint, data: [YourDataModel]) { if data.isEmpty { // 数据为空,完全移除TableView if tableView.superview != nil { tableView.removeFromSuperview() heightConstraint.isActive = false // 关闭约束避免内存泄漏 } } else { // 数据不为空,确保TableView在StackView里 if tableView.superview == nil { mainStackView.addArrangedSubview(tableView) heightConstraint.isActive = true } // 更新数据源 if tableView == tableView1 { dataSource1 = data } else { dataSource2 = data } // 调整高度 updateTableViewHeight(tableView, heightConstraint: heightConstraint) } }
第五步:API请求回调里调用逻辑
最后在API请求完成后,把数据传进去处理:
private func fetchDataFromAPI() { // 这里替换成你的实际API请求逻辑 APIManager.fetchData { [weak self] result in guard let self = self else { return } switch result { case .success(let response): // 处理第一个TableView self.handleTableViewVisibility(tableView: self.tableView1, heightConstraint: self.tableView1HeightConstraint, data: response.dataList1) // 处理第二个TableView self.handleTableViewVisibility(tableView: self.tableView2, heightConstraint: self.tableView2HeightConstraint, data: response.dataList2) case .failure(let error): print("API请求失败:\(error.localizedDescription)") // 请求失败时也移除TableView(或者你可以加错误提示视图) self.handleTableViewVisibility(tableView: self.tableView1, heightConstraint: self.tableView1HeightConstraint, data: []) self.handleTableViewVisibility(tableView: self.tableView2, heightConstraint: self.tableView2HeightConstraint, data: []) } } }
额外提醒
- 确保你的自定义Cell已经正确设置了Auto Layout约束,不然
automaticDimension没法正确计算高度 - 如果用UITableViewDiffableDataSource(iOS 13+),可以不用手动
reloadData,直接apply快照,代码会更简洁
内容的提问来源于stack exchange,提问作者Rohini G
相关产品推荐
相关产品推荐

