Swift开发:UIViewController内UITableView刷新失效求助
问题分析与修复方案
看起来你遇到的核心问题是点击日期按钮后,没有正确更新数据源showOnDate,也没有完整触发表格刷新的流程。我帮你梳理下几个关键问题和修复步骤:
1. 点击事件缺少数据源更新逻辑
你的isClickedDate方法只更新了selectedDay,但没有调用getShowList去重新筛选对应日期的场次并赋值给showOnDate——而表格的展示完全依赖showOnDate的数据。这就是点击按钮后表格没变化的核心原因。
修复后的点击方法
@IBAction func isClickedDate(_ sender: UIButton) { // 安全处理按钮文本转Int,避免强制解包崩溃 guard let dayText = sender.titleLabel?.text, let selectedDay = Int(dayText) else { print("按钮日期格式无效") return } self.selectedDay = selectedDay // 确保选中影院不为空,避免强制解包崩溃 guard let selectedTheater = self.selectedTheater else { print("未选中任何影院") showOnDate = [] showtimeTable.reloadData() return } // 更新数据源:获取对应日期的场次 showOnDate = getShowList(date: selectedDay) // 主线程刷新表格(UI操作必须在主线程执行) DispatchQueue.main.async { self.showtimeTable.reloadData() } }
2. 检查dateComponents的定义
你的getShowList方法里用了dateComponents来提取日期的day,但如果这个变量没有包含.day组件,dateTimeComponents.day会是nil,导致筛选条件永远不成立,showOnDate会是空数组。
确保你在类里正确定义了dateComponents:
// 放在ShowtimeViewController类的顶部 private let dateComponents: Set<Calendar.Component> = [.day, .hour, .minute]
3. 首次加载的数据源初始化
虽然你说首次加载默认显示今日排期,但最好确认viewDidLoad里是否正确初始化了showOnDate:
override func viewDidLoad() { super.viewDidLoad() showtimeTable.delegate = self showtimeTable.dataSource = self showtimeTable.tableFooterView = UIView() // 首次加载获取今日日期的场次 let todayDay = Calendar.current.component(.day, from: Date()) selectedDay = todayDay if let theater = selectedTheater { showOnDate = getShowList(date: todayDay) } else { showOnDate = [] } showtimeTable.reloadData() }
4. 可选值安全处理建议
你的代码里有不少强制解包(比如selectedTheater!、dateTimeComponents.hour!),很容易导致崩溃。建议在willDisplay方法里也做安全处理:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { guard let cell = cell as? ShowtimeTableViewCell else { return } let show = showOnDate[indexPath.section] let dateTimeComponents = Calendar.current.dateComponents(dateComponents, from: show.sDate) // 安全处理小时和分钟,避免nil崩溃 let hour = dateTimeComponents.hour ?? 0 let minute = dateTimeComponents.minute ?? 0 cell.showTime.text = String(format: "%02d:%02d", hour, minute) cell.showImage.image = show.sFilm.fPoster cell.showName.text = "\(show.sFilm.fName) (\(show.sFilm.fYear))" }
验证步骤
- 点击日期按钮时,先打印
showOnDate.count,确认数据源是否有数据 - 检查
getShowList里的筛选逻辑,确认date和dateTimeComponents.day是否匹配(比如今日的day是25,按钮文本是不是"25")
这样修改后,点击按钮应该就能正确切换不同日期的排期了。
内容的提问来源于stack exchange,提问作者hell2809
相关产品推荐
相关产品推荐

