You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxSwift下UITableView两种不同高度cell仅显示最大高度问题求解

问题原因
  • 你写的cell类型判断逻辑错误:workoutsTableView.cellForRow(at: indexPath) == FutureSessionCell() 是将当前indexPath的cell和新创建的FutureSessionCell实例做内存地址对比,永远返回false,所以所有场景都进入else分支返回390,这是所有cell都显示大高度的直接原因。
  • heightForRowAt的调用时机早于cell的渲染完成,此时调用cellForRow(at:)无法获取到正确的cell实例,还会触发heightForRowAt的循环调用,引发性能损耗甚至死循环。
  • 搭配RxSwift的rx.items绑定数据源时,优先适配Rx的使用规范,不要混用传统代理的硬编码高度判断,避免逻辑割裂。
修复方案

方案1:自动高度适配(推荐)

如果你的两个cell内部已经通过AutoLayout将子控件撑满contentView的上下边缘,直接开启UITableView的自动高度即可,不需要手动判断返回高度:

  1. 在viewDidLoad中添加以下配置:
// 开启自动高度
workoutsTableView.rowHeight = UITableView.automaticDimension
// 设置预估高度,值接近两种cell的平均高度即可,用于提升滚动性能
workoutsTableView.estimatedRowHeight = 300
  1. 直接删除你当前实现的heightForRowAt代理方法即可。

方案2:固定高度手动返回

如果业务需求必须使用固定高度,不要通过cell判断类型,直接通过数据源的属性判断即可:
你的cell类型由数据源的workout.createdByCoach字段决定,直接取对应indexPath的数据源字段判断即可,修改heightForRowAt逻辑:

extension CalendarVC: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let currentWorkout = vm.workoutForOneDay.value[indexPath.row]
        return currentWorkout.createdByCoach ? 190 : 390
    }
}

同时需要将代理和Rx绑定,在bindTableViewWorkouts方法中添加代理绑定逻辑:

workoutsTableView.rx.setDelegate(self)
    .disposed(by: disposeBag)

内容的提问来源于stack exchange,提问作者Karl Mcgeough

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:06:06