在其他屏幕中更新绑定后,SwiftUI 列表行未刷新

Posted

技术标签:

【中文标题】在其他屏幕中更新绑定后,SwiftUI 列表行未刷新【英文标题】:SwiftUI List Rows Not Refreshed After Updating Binding In Other Screen 【发布时间】:2020-01-30 14:36:15 【问题描述】:

我有一个简单的 watchOS SwiftUI 应用程序。该应用程序具有三个屏幕。第一个屏幕由List 的项目组成。当你按下该项目时,它会重定向到另一个屏幕,当你点击那里的按钮时,它会打开一个.sheet View,它允许你编辑列表中的项目。

第一个视图如下所示:


class Object: NSObject 

    var title: String

    init(title: String) 
        self.title = title
    



struct Row: View 

    @Binding var object: Object

    var body: some View 
        Text(self.object.title)
    



struct ContentView: View 

    @State private var objects = [Object]()

    var body: some View 
        NavigationView 
            List 
                ForEach(objects.indices, id: \.self)  idx in
                    NavigationLink(destination: SecondView(object: self.$objects[idx])) 
                        Row(object: self.$objects[idx])
                    
                
            
        
        .onAppear 
            self.objects = [
                Object(title: "Test 1"),
                Object(title: "Test 2")
            ]
        
    


这些是第二个和第三个视图:

struct SecondView: View 

    @Binding var object: Object
    @State private var showPicker: Bool = false

    var body: some View 
        VStack 
            Text(object.title)
            Button(action: 
                self.showPicker.toggle()
            ) 
                Text("Press Here")
            
        
        .sheet(isPresented: $showPicker) 
            ThirdView(object: self.$object)
        
    



struct ThirdView: View 

    @Binding var object: Object

    var body: some View 
        VStack 
            Text(object.title)
            Button(action: 
                self.update()
            , label: 
                Text("Tap here")
            )
        
    

    func update() 
        let newObj = self.object
        newObj.title = "Hello, World!"
        self.object = newObj
    


我希望,每当我在第三个视图中点击按钮时,Binding(以及 State)都会更新为“Hello, World”。然而,情况并非如此,尽管不是立即发生。

我目前看到的情况是,当我在第三个视图中点击按钮时,该视图中的 Text 不会更新。当我关闭第三个视图并返回第二个视图时,我确实看到了“Hello, World”。但是当我返回列表时,该行仍然具有旧值。

我注意到的另一件事是,当我直接填充对象数组时,如下所示:

@State private var objects = [Object(title: "Test 1"), Object(title: "Test 2")]

并删除.onAppear 中的数组填充,这完全符合我的预期(所有内容都会立即更新为“Hello, World”。

有谁知道我在这里做错了什么或者我可能会遇到错误?

谢谢!

【问题讨论】:

【参考方案1】:

复杂对象必须是符合@ObservableObject 的类。 观察到的 ivars 需要发布。

class Object: ObservableObject 
  @Published var title: String
  [...]

观察视图会将它们用作@ObservedObject

struct Row: View 
  @ObservedObject var object: Object
  [...]

您可能需要为您的列表创建一个对象包装器

class ObjectList: ObservableObject 
  @Published var objects: [Object]
  [...]

【讨论】:

以上是关于在其他屏幕中更新绑定后,SwiftUI 列表行未刷新的主要内容,如果未能解决你的问题,请参考以下文章

从 SwiftUI 中的列表中删除绑定

删除具有绑定布尔值的列表项 - SwiftUI

SwiftUI:如何更新 NavigationView 详细信息屏幕?

SwiftUI 中的底部优先滚动

SwiftUI 中的列表视图占据整个屏幕高度

升级到 Xcode 12 后,SwiftUI 列表视图有不同的颜色深浅