如何根据当日时间自动滚动UICollectionView单元格以展示对应公交班次
公交时刻表UICollectionView自动滚动实现方案
核心逻辑说明
- 先建立班次时间和数组索引的映射关系,所有班次转换为当日总分钟数存储,和
busDepartureHoursList一一对应,方便快速匹配 - 无需后台驻留任务,每次进入页面时重新读取系统当前时间计算目标索引,App重启后依然生效
- 匹配规则完全符合需求:
- 00:30 至 次日6:00 区间,自动滚动到6:00对应的首班次
- 运营时段内,14:30前展示14:00班次、14:30后展示15:00班次,以此类推
代码实现
1. 新增属性定义
在HomeViewController中新增以下属性:
// 所有班次对应的当日总分钟数,和busDepartureHoursList索引一一对应 lazy var busTimeMinutes: [Int] = { var minutes = [Int]() var current = 6 * 60 // 首班6:00对应的分钟数 while current <= 24 * 60 + 30 { // 末班00:30对应的分钟数 minutes.append(current) current += 30 } return minutes }() // 前台自动更新用定时器 var autoScrollTimer: Timer?
2. 新增索引计算与滚动方法
// 计算当前需要滚动到的目标索引 private func getTargetIndex() -> Int { let calendar = Calendar.current let now = Date() let currentMinutes = calendar.component(.hour, from: now) * 60 + calendar.component(.minute, from: now) // 非运营时段返回首班索引 if currentMinutes < 6 * 60 || currentMinutes >= 24 * 60 + 30 { return 0 } // 运营时段按规则计算索引 let timeOffset = currentMinutes - 6 * 60 var targetIndex = timeOffset / 30 // 到半点后切换到下下个班次,匹配需求规则 if timeOffset % 30 >= 0 { targetIndex += 1 } // 索引越界处理 return min(targetIndex, busTimeMinutes.count - 1) } // 执行滚动操作 private func scrollToTargetBus() { let targetIndex = getTargetIndex() guard targetIndex < busHoursList.count else { return } collectionView.scrollToItem( at: IndexPath(row: targetIndex, section: 0), at: .centeredHorizontally, animated: true ) }
3. 调用时机配置
在HomeViewController的生命周期方法中添加调用逻辑:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 每次进入页面立刻计算滚动 scrollToTargetBus() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 前台运行时每分钟检查一次,自动更新滚动位置 autoScrollTimer = Timer.scheduledTimer( withTimeInterval: 60, repeats: true, block: { [weak self] _ in self?.scrollToTargetBus() } ) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 离开页面销毁定时器,避免内存泄漏 autoScrollTimer?.invalidate() autoScrollTimer = nil }
4. 原有代码修正
你现有代码中的cellForItemAt方法缺少返回值,需要补全:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let busCell = collectionView.dequeueReusableCell(withReuseIdentifier: "busCellID", for: indexPath) as! BusCollectionViewCell busCell.layer.borderWidth = 0.6 busCell.layer.cornerRadius = 15 busCell.layer.borderColor = CGColor.init(red: 170/250, green: 170/250, blue: 170/250, alpha: 1) busCell.setupDepartureHours(withText: busDepartureHoursList[indexPath.row]) // 补全返回语句 return busCell }
内容的提问来源于stack exchange,提问作者fardi Clk
相关产品推荐
相关产品推荐

