【问题标题】:View is not updated using @State property wrapper in SwiftUI在 SwiftUI 中使用 @State 属性包装器未更新视图
【发布时间】:2020-05-04 19:44:00
【问题描述】:

使用@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
}

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

错误:“变异运算符的左侧不可变:'person' 是 'let' 常量”

我以为我理解 Struct、Class、@State 的含义……我想不明白……感谢您提供任何解决方案。

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    struct 通过引用传递,因此您不需要 @State,因为 ObservableObject 已经收到更新。

    这是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")
            }
        }
    }
    
    

    【讨论】:

    • 感谢您的解决方案。我真的不明白为什么person.age += 1 在 ForEach 循环中不起作用并输出错误:“变异运算符的左侧不可变:'person' 是 'let' 常量”。你能指出我正确的方向吗?谢谢!
    • 它不起作用,因为在ForEach 循环中,person 是一个常量,不能修改。一般来说,闭包值是一个常数。
    猜你喜欢
    • 2021-10-19
    • 2021-01-06
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 2020-10-21
    相关资源
    最近更新 更多