SwiftUI中WheelPickerStyle的Picker滚动时新旧值跳变问题求助
解决Picker滚动时短暂跳回旧值的问题
问题原因
你遇到的Picker滚轮跳变问题,本质是因为IntervalSet是值类型(推测为struct),每次修改其minutes或seconds属性时,会生成新的IntervalSet实例,导致子视图的@Binding触发视图重绘。Picker在重绘过程中会短暂恢复旧值,再同步新选中的值。
解决方案
方案1:拆分Binding为单个属性
直接将子视图的Binding拆分为单独的minutes和seconds,避免整个结构体更新带来的视图刷新问题:
子视图代码修改:
struct ChildView: View { @Binding var minutes: Int @Binding var seconds: Int var body: some View { HStack { Picker("", selection: $minutes){ ForEach(0..<60, id: \.self) { i in Text("\(i) min").tag(i) } }.pickerStyle(WheelPickerStyle()) Picker("", selection: $seconds){ ForEach(0..<60, id: \.self) { i in Text("\(i) sec").tag(i) } }.pickerStyle(WheelPickerStyle()) } } }
父视图调用子视图时:
ChildView(minutes: $set.minutes, seconds: $set.seconds)
方案2:给子视图添加Equatable实现
如果必须绑定整个IntervalSet,可以让子视图遵循Equatable协议,只在属性真正变化时才重绘:
子视图代码修改:
struct ChildView: View, Equatable { static func == (lhs: ChildView, rhs: ChildView) -> Bool { // 仅比较需要关注的属性 lhs.set.minutes == rhs.set.minutes && lhs.set.seconds == rhs.set.seconds } @Binding var set: IntervalSet var body: some View { HStack { Picker("", selection: $set.minutes){ ForEach(0..<60, id: \.self) { i in Text("\(i) min").tag(i) } }.pickerStyle(WheelPickerStyle()) Picker("", selection: $set.seconds){ ForEach(0..<60, id: \.self) { i in Text("\(i) sec").tag(i) } }.pickerStyle(WheelPickerStyle()) } } }
父视图调用时添加.equatable()修饰符:
ChildView(set: $set).equatable()
额外检查
确认父视图中没有其他代码(比如onAppear、定时器或其他回调)会频繁修改set的值,这也可能导致Picker的selection被多次赋值,引发跳变。
内容的提问来源于stack exchange,提问作者user3746381
相关产品推荐
相关产品推荐

