为什么watchOS中Picker会触发“ScrollView contentOffset binding has been read”警告
watchOS Picker跳转警告修复方案
你遇到的警告原文如下:
"ScrollView contentOffset binding has been read; this will cause grossly inefficient view performance as the ScrollView's content will be updated whenever its contentOffset changes. Read the contentOffset binding in a view that is not parented between the creator of the binding and the ScrollView to avoid this."
问题原因
- watchOS端SwiftUI的
Picker默认基于ScrollView实现滚轮选择效果,未明确指定样式时,系统内部会主动读取ScrollView的contentOffset绑定用于适配布局 - 你当前使用的已废弃的
NavigationView导航栈实现存在bug,跳转时父视图会意外读取子页面Picker内部的ScrollView偏移量绑定,触发性能警告
修复方案
按以下两个步骤修改即可消除警告:
- 替换根视图废弃的
NavigationView为watchOS 9+推荐的NavigationStack,如果需要兼容更低版本,可以给NavigationView加.navigationViewStyle(.stack)显式指定样式 - 给
DistanceSelectView中的Picker明确指定.pickerStyle(.wheel)样式,避免系统默认样式的多余绑定读取
修改后的代码示例
PickerTestApp 代码
import SwiftUI @main struct PickerTestApp: App { var body: some Scene { WindowGroup { NavigationStack { ContentView() } // 兼容watchOS 8及更低版本可替换为以下代码 // NavigationView { // ContentView() // } // .navigationViewStyle(.stack) } } }
DistanceSelectView 代码
import SwiftUI struct DistanceSelectView: View { @State var age = 1 var body: some View { VStack { Picker(selection: $age, label: Text("Select your age.[\(age)]")) { ForEach(10 ..< 100, id: \.self) { num in Text("\(num)") } } .pickerStyle(.wheel) } } }
内容的提问来源于stack exchange,提问作者Janis Jakaitis
相关产品推荐
相关产品推荐

