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

如何根据当日时间自动滚动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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:30:01