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

为什么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偏移量绑定,触发性能警告

修复方案

按以下两个步骤修改即可消除警告:

  1. 替换根视图废弃的NavigationView为watchOS 9+推荐的NavigationStack,如果需要兼容更低版本,可以给NavigationView加.navigationViewStyle(.stack)显式指定样式
  2. 给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:36:05