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

SwiftUI自定义Picker超过最大时长时重置选中值的实现问题

解决方案

核心思路

Wheel Picker的选择变化是通过绑定值更新触发的,不需要依赖点击手势,直接用onChange修饰符监听hours和minutes的变化,在值更新后执行校验逻辑即可。

修改后的完整代码

var body: some View {
    let hours = [Int](0...maxHours)
    let minutes = [Int](0...maxMinutes)
    GeometryReader { geometry in
        HStack(spacing: 0) {
            Picker(selection: $selection.hours, label: Text("")) {
                // 修正遍历逻辑,直接用hours数组避免遗漏最大值
                ForEach(hours, id: \.self) { hour in
                    Text("\(hour) hr")
                        .foregroundColor(Color(Asset.Color.V2.white.color))
                }
            }
            .pickerStyle(.wheel)
            .frame(width: geometry.size.width / 2, height: geometry.size.height)
            // 监听小时选择变化
            .onChange(of: selection.hours) { _ in
                checkAndResetDuration()
            }

            Picker(selection: $selection.minutes, label: Text("")) {
                // 同理修正分钟遍历逻辑
                ForEach(minutes, id: \.self) { minute in
                    Text("\(minute) min")
                        .foregroundColor(Color(Asset.Color.V2.white.color))
                }
            }
            .pickerStyle(.wheel)
            .frame(width: geometry.size.width / 2, height: geometry.size.height)
            // 监听分钟选择变化
            .onChange(of: selection.minutes) { _ in
                checkAndResetDuration()
            }
        }
    }
}

// 提取校验逻辑为单独方法,提升可读性
private func checkAndResetDuration() {
    let totalSeconds = selection.hours * 3600 + selection.minutes * 60
    if totalSeconds > Int(maxDurationSeconds) {
        selection.hours = 0
        selection.minutes = 0
    }
}

关键说明

  1. 修正Picker遍历逻辑:原代码ForEach(0..<maxHours)会遗漏maxHours选项(比如maxHours=24时只能选到23),直接遍历hours数组可确保所有选项都被包含。
  2. 用onChange监听值变化:无论用户调整小时还是分钟,只要绑定值更新就触发校验,完美适配Wheel Picker的交互逻辑,比点击手势更准确。
  3. 正确计算总秒数:原代码将小时直接视为秒数是错误的,需转换为小时数*3600 + 分钟数*60才是正确的总秒数。
  4. 直接操作绑定值:无需访问wrappedValue,直接给selection.hours和selection.minutes赋值即可,SwiftUI会自动处理视图更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:15:27