swift - 在 SwiftUI 中使用`@Binding` 初始化`@State`ful 结构
问题描述
我有一个应用程序,其中两个不同的结构依赖于单独的数据,当我更改该数据时,两个结构都需要了解更改。我想我可以通过重构或使用 来解决问题@EnvironmentObject
,但我想了解为什么这段代码不起作用。在SceneDelegate.swift
iOS 项目中,设置contentView
withlet contentView = StateTestTopView()
然后使用以下代码创建文件:
import SwiftUI
struct Person { @Binding var name: String }
struct Character { @Binding var name: String }
struct StateTestTopView: View {
@State private var name: String = "Bilbo"
var body: some View {
VStack {
StateTestPickerView(name: $name)
Spacer()
Text("Global name selection is \(name)").font(.title)
}
}
}
struct StateTestPickerView: View {
@Binding var name: String
@State private var person: Person
@State private var character: Character
init(name: Binding<String>) {
self._name = name
self._person = State(initialValue: Person(name: name))
self._character = State(initialValue: Character(name: name))
}
var body: some View {
VStack{
Picker(selection: $name,
label: Text(verbatim: "Selected name: \(name)")) {
ForEach(["Sam", "Gandalf", "Gollum"], id: \.self) { name in
Text(name)
}
}
Text("You picked \(name)")
ShowPersonAndCharacter(
person: self.$person, character: self.$character)
}
}
}
struct ShowPersonAndCharacter: View {
@Binding var person: Person
@Binding var character: Character
var body: some View {
Text("\(person.name) is great! \(character.name) is the same person!")
}
}
问题是 and 结构的has ,ShowPersonAndCharacter
但是当底层数据发生变化时,绑定的结构不会更新。我怀疑问题出在 Picker 视图初始化程序中:@Binding
Person
Character
@Binding var name: String
@State private var person: Person
@State private var character: Character
init(name: Binding<String>) {
self._name = name
self._person = State(initialValue: Person(name: name))
self._character = State(initialValue: Character(name: name))
}
在这里,我认为Person
andCharacter
结构是使用绑定 String 的快照创建的,实际上并没有得到绑定。我不确定如何解决这个问题,或者即使我的诊断是远程正确的。
有任何想法吗?
谢谢你的时间!
解决方案
我同意@Asperi,绑定旨在用于视图而不是模型。事实上,在这种情况下,您根本不需要模型进行绑定。由于它@Binding var name: String
是一个绑定,StateTestPickerView
因此它会在更新后立即自行更新视图。请参阅以下代码修改。这对我来说非常好:
struct Person { var name: String }
struct Character { var name: String }
struct StateTestTopView: View {
@State private var name: String = "Bilbo"
var body: some View {
VStack {
StateTestPickerView(name: $name)
Spacer()
Text("Global name selection is \(name)").font(.title)
}
}
}
struct StateTestPickerView: View {
@Binding var name: String
var body: some View {
VStack{
Picker(selection: $name,
label: Text(verbatim: "Selected name: \(name)")) {
ForEach(["Sam", "Gandalf", "Gollum"], id: \.self) { name in
Text(name)
}
}
Text("You picked \(name)")
ShowPersonAndCharacter(person: Person(name: self.name),
character: Character(name: self.name))
}
}
}
struct ShowPersonAndCharacter: View {
var person: Person
var character: Character
var body: some View {
Text("\(person.name) is great! \(character.name) is the same person!")
}
}
请注意,绑定属性包装器已从模型中删除。此外,StateTestPickerView
在以下代码中使用名称绑定直接调用视图:ShowPersonAndCharacter(person: Person(name: self.name), character: Character(name: self.name))
推荐阅读
- reactjs - 胜利图表:使用带有条形图的标签
- python - 有没有办法使用 SQL 表达式遍历 s3 对象内容?
- c# - 检查搜索是否忽略了某些关键字或我的查询是错误的?
- php - 获取 php curl GET 命令返回 'Uncaught (in promise) SyntaxError: Unexpected number in JSON at position 4814'
- hdmi - 将 HDMI 数据读取为流数据
- python - Paho MQTT:未发送消息队列并重新启动
- java - 有没有一种简单的方法来反转经历溢出的整数函数?
- reactjs - React Hooks - 将进程仅传递一次道具的逻辑放在哪里?
- javascript - 使用 html CSS 和 javascript 创建轮播的问题
- xml - 如何将带有位置的 XML 文件集成到 ReactJS 谷歌地图中?