在SwiftUI中使用@State属性包装器,视图没有更新。

问题描述 投票:0回答:1

使用@State包装器时,视图不会被更新。不使用@State包装器也能更新视图,但必须手动更新。

import SwiftUI

struct SwiftUIView: View {
    @ObservedObject var people: People
    var body: some View {
        VStack {
            ForEach(people.peoples){ person in
                HStack{
                    Text("\(person.age)")
                    if person.ismale {
                        Text("Male")
                    } else {
                        Text("Female")
                    }
                    Button(action:{ person.age += 1}){
                        Text("Age+1")
                    }
                }
            }
        }
    }
}

struct Person: Identifiable{
    var id = UUID()
    @State var age: Int
    var ismale = true
}

class People: ObservableObject {
    @Published var peoples: [Person]
    init() {
        self.peoples = [
            Person(age: 10),
            Person(age: 12, ismale: false)
        ]
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView(people: People())
    }
}

出于某种原因,当按钮被点击时,视图没有任何变化。

如果我把它改为

Button(action:{ **self.people.peoples[0].age += 1** }){
       Text("Age+1")
}
...

struct Person: Identifiable{
    var id = UUID()
    **var age: Int**
    var ismale = true
}

它更新,但按钮不会是动态的。然而,如果我做 person.age += 1 在ForEach循环中,不使用 @State 变量年龄的包装器。

错误:"突变操作符的左侧不能突变:'person'是一个'let'常数"

我想我明白什么是结构,类,@状态的意思... ... 我想不明白... 谢谢你的解答。

swift swiftui
1个回答
0
投票

struct 都是通过引用传递的,所以你不需要使用@State包装器。@State' as theObservableObject`已经收到了更新。

这里是 Person 结构

struct Person: Identifiable{
    var id = UUID()
    var age: Int
    var ismale = true
}

还有 SwiftUIView. 我去掉了 If 语句,这样代码会更简洁一些。

ForEach(people.peoples.indices, id: \.self){ index in
    HStack{
        Text("\(self.people.peoples[index].age)")
        Text(self.people.peoples[index].ismale ? "Male" : "Female")
        Button(action:{ self.people.peoples[index].age += 1 }){
            Text("Age+1")
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.