SwiftUI中Form嵌套TextField时初始值无法正常显示问题
问题原因
这是iOS 15版本中Form组件的渲染时序特性导致的:
- iOS 15下Form本质是UITableView的封装,属于懒加载的滚动类容器,首次渲染优先级高于NavigationView的
onAppear回调触发时机 - 你的代码中本地
@State变量初始赋值为dummy/空值,等onAppear触发时才修改为正确的user属性值,此时Form已经完成了首次渲染,没有捕获到状态变更的刷新信号,所以不会更新TextField的展示内容,直到点击TextField激活输入状态时,才会重新读取绑定的状态值完成刷新 - 替换为VStack后正常是因为VStack属于静态堆叠容器,只要绑定的状态发生变化,会立刻触发所有子视图重绘,不存在懒加载的时序问题
解决方案
方案1(最推荐):在初始化阶段给本地State赋值
@State的初始值仅会在视图首次创建时赋值一次,直接在ContentView的自定义构造方法中读取传入的user值初始化本地状态,完全避开onAppear的时序问题。修改后的ContentView代码如下:
struct ContentView: View { @Binding var user: User @State private var name: String @State private var email: String // 自定义初始化方法 init(user: Binding<User>) { self._user = user self._name = State(initialValue: user.wrappedValue.name) self._email = State(initialValue: user.wrappedValue.email) } var body: some View { NavigationView { Form { TextField("Name", text: $name) TextField("Email", text: $email) } .navigationTitle("Edit user") .toolbar { Button("Save") { user.name = name user.email = email } } } // 原有的onAppear代码可以直接删除 } }
方案2:将onAppear挂载到Form上
如果确实需要保留onAppear逻辑,可以把onAppear修饰符从NavigationView移动到Form上,Form的onAppear触发时机和自身渲染时机匹配,修改后可以正确触发刷新:
var body: some View { NavigationView { Form { TextField("Name", text: $name) TextField("Email", text: $email) } .navigationTitle("Edit user") .toolbar { Button("Save") { user.name = name user.email = email } } .onAppear { // 移到Form的修饰符里 name = user.name email = user.email } } }
内容的提问来源于stack exchange,提问作者Shuji Fukumoto
相关产品推荐
相关产品推荐

