如何在 swiftui 中使用 @Published 属性 包装器更改选择器内的值
How to change values inside a picker using @Published property wrapper in swiftui
您好,我在 swiftui 中遇到了选择器视图的问题
我创建了一个只有 class 这样的文件
import Foundation
import SwiftUI
class something: ObservableObject {
@Published var sel = 0
}
然后我创建了 2 个视图
import SwiftUI
struct ContentView: View {
@StateObject var hihi: something
var characters = ["Makima", "Ryuk", "Itachi", "Gojou", "Goku", "Eren", "Levi", "Jiraya", "Ichigo", "Sukuna"]
var body: some View {
VStack {
Section{
Picker("Please choose a character", selection: $hihi.sel) {
ForEach(characters, id: \.self) { name in
Text(name)
}
}
Text(characters[hihi.sel])
}
now(hihi: something())
}
}
}
struct now: View {
@StateObject var hihi: something
var body: some View {
Text("\(hihi.sel)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(hihi: something())
}
}
现在面临的问题是代码编译但选择器不工作它不会更改为数组中的任何其他值我提供它返回到其原始值,前提是第 0 个索引“ Makima”,它不会 select 任何其他选项,为什么?
请帮忙
存在三个问题,主要的一个是选择不匹配。
在 Picker
中,您的选择基于每个字符的字符串值。这是因为 ForEach
通过 name
字符串标识每个 Text
,因为您使用了 id: \.self
.
但是,您的 something
模型(按照惯例,理想情况下应该以大写字母开头)有一个数字选择。因为 Picker
中的项目有 String
个 ID,而这是一个 Int
,无法设置选择。
您可以将模型更改为:
class something: ObservableObject {
@Published var sel = "Makima"
}
这还需要在body中稍作改动:
VStack {
Section{
Picker("Please choose a character", selection: $hihi.sel) {
ForEach(characters, id: \.self) { name in
Text(name)
}
}
Text(hihi.sel) // Now getting string directly
}
now(hihi: something())
}
请注意,我们现在有两个显示所选角色的视图 - 但只有最上面的一个更新。底部的视图现在可能是多余的(now
视图),但我将向您展示如何让它正常工作。这是我们遇到第二个问题的地方:
您在将 something()
传递给 now
时创建了一个新实例(同样,应该以大写字母开头)。这意味着 ContentView
中存储的 hihi
的当前实例不会被传递。您只是在创建一个使用默认值的 something
的新实例。这完全独立于 hihi
实例。
替换:
now(hihi: something())
与:
now(hihi: hihi)
最后一个可能不太明显的问题是,您不应该在 now
中使用 @StateObject
,因为它不 拥有 [=68] =] object/data。相反,传入了 object,因此您应该使用 @ObservedObject
。尽管该示例现在即使没有此更改也能正常工作,但您稍后在尝试更改 now
视图中的 object 时会遇到问题。
将 now
中的 @StateObject
替换为 @ObservedObject
。
完整答案(something
在ContentView
中初始化只是为了测试方便):
struct ContentView: View {
@StateObject var hihi: something = something()
var characters = ["Makima", "Ryuk", "Itachi", "Gojou", "Goku", "Eren", "Levi", "Jiraya", "Ichigo", "Sukuna"]
var body: some View {
VStack {
Section{
Picker("Please choose a character", selection: $hihi.sel) {
ForEach(characters, id: \.self) { name in
Text(name)
}
}
Text(hihi.sel)
}
now(hihi: hihi)
}
}
}
struct now: View {
@ObservedObject var hihi: something
var body: some View {
Text(hihi.sel)
}
}
class something: ObservableObject {
@Published var sel = "Makima"
}
您好,我在 swiftui 中遇到了选择器视图的问题
我创建了一个只有 class 这样的文件
import Foundation
import SwiftUI
class something: ObservableObject {
@Published var sel = 0
}
然后我创建了 2 个视图
import SwiftUI
struct ContentView: View {
@StateObject var hihi: something
var characters = ["Makima", "Ryuk", "Itachi", "Gojou", "Goku", "Eren", "Levi", "Jiraya", "Ichigo", "Sukuna"]
var body: some View {
VStack {
Section{
Picker("Please choose a character", selection: $hihi.sel) {
ForEach(characters, id: \.self) { name in
Text(name)
}
}
Text(characters[hihi.sel])
}
now(hihi: something())
}
}
}
struct now: View {
@StateObject var hihi: something
var body: some View {
Text("\(hihi.sel)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(hihi: something())
}
}
现在面临的问题是代码编译但选择器不工作它不会更改为数组中的任何其他值我提供它返回到其原始值,前提是第 0 个索引“ Makima”,它不会 select 任何其他选项,为什么? 请帮忙
存在三个问题,主要的一个是选择不匹配。
在 Picker
中,您的选择基于每个字符的字符串值。这是因为 ForEach
通过 name
字符串标识每个 Text
,因为您使用了 id: \.self
.
但是,您的 something
模型(按照惯例,理想情况下应该以大写字母开头)有一个数字选择。因为 Picker
中的项目有 String
个 ID,而这是一个 Int
,无法设置选择。
您可以将模型更改为:
class something: ObservableObject {
@Published var sel = "Makima"
}
这还需要在body中稍作改动:
VStack {
Section{
Picker("Please choose a character", selection: $hihi.sel) {
ForEach(characters, id: \.self) { name in
Text(name)
}
}
Text(hihi.sel) // Now getting string directly
}
now(hihi: something())
}
请注意,我们现在有两个显示所选角色的视图 - 但只有最上面的一个更新。底部的视图现在可能是多余的(now
视图),但我将向您展示如何让它正常工作。这是我们遇到第二个问题的地方:
您在将 something()
传递给 now
时创建了一个新实例(同样,应该以大写字母开头)。这意味着 ContentView
中存储的 hihi
的当前实例不会被传递。您只是在创建一个使用默认值的 something
的新实例。这完全独立于 hihi
实例。
替换:
now(hihi: something())
与:
now(hihi: hihi)
最后一个可能不太明显的问题是,您不应该在 now
中使用 @StateObject
,因为它不 拥有 [=68] =] object/data。相反,传入了 object,因此您应该使用 @ObservedObject
。尽管该示例现在即使没有此更改也能正常工作,但您稍后在尝试更改 now
视图中的 object 时会遇到问题。
将 now
中的 @StateObject
替换为 @ObservedObject
。
完整答案(something
在ContentView
中初始化只是为了测试方便):
struct ContentView: View {
@StateObject var hihi: something = something()
var characters = ["Makima", "Ryuk", "Itachi", "Gojou", "Goku", "Eren", "Levi", "Jiraya", "Ichigo", "Sukuna"]
var body: some View {
VStack {
Section{
Picker("Please choose a character", selection: $hihi.sel) {
ForEach(characters, id: \.self) { name in
Text(name)
}
}
Text(hihi.sel)
}
now(hihi: hihi)
}
}
}
struct now: View {
@ObservedObject var hihi: something
var body: some View {
Text(hihi.sel)
}
}
class something: ObservableObject {
@Published var sel = "Makima"
}