【问题标题】:Clear SwiftUI list in NavigationView does not properly go back to default在 NavigationView 中清除 SwiftUI 列表未正确返回默认值
【发布时间】:2021-07-05 13:23:26
【问题描述】:

下面的简单导航演示演示了我的问题的一个示例:

  • NavigationView 中的 SwiftUI 列表填充了来自数据模型 Model 的数据。
  • 可以选择列表项,并且 NavigationView 正在链接右侧的另一个视图(此处使用 destination 演示)
  • 可以从模型中清除数据 - SwiftUI 列表为空
  • 模型数据可以在以后的某个时间点用新数据填充
import SwiftUI

// Data model
class Model: ObservableObject {
    // Example data
    @Published var example: [String] = ["Data 1", "Data 2", "Data 3"]
    @Published var selected: String?
}

// View
struct ContentView: View {
    @ObservedObject var data: Model = Model()
    
    var body: some View {
        VStack {
            // button to empty data set
            Button(action: {
                data.selected = nil
                data.example.removeAll()
            }) {
                Text("Empty Example data")
            }
            
            NavigationView {
                // data list
                List {
                    ForEach(data.example, id: \.self) { element in
                        // navigation to "destination"
                        NavigationLink(destination: destination(element: element), tag: element, selection: $data.selected) {
                            Text(element)
                        }
                    }
                }
                
                // default view when nothing is selected
                Text("Nothing selected")
            }
        }
    }
    
    func destination(element: String) -> some View {
        return Text("\(element) selected")
    }
}

当我单击“空示例数据”按钮时会发生什么,列表将被正确清除。但是,选择是持久的,当没有选择任何内容时,NavigationView 不会跳回默认视图:

我希望视图 Text("Nothing selected") 正在加载。

我是否忽略了一些重要的事情?

【问题讨论】:

    标签: swift macos swiftui


    【解决方案1】:

    当你改变 data.example 在按钮中,左侧面板发生更改,因为列表已更改。 但是右侧没有,因为那里没有发生任何变化,只有列表发生了变化。 ForEach 不会重新绘制“目标”视图。

    你有一个“ObservedObject”,它的目的是跟踪变化,所以使用它 你可以实现你想要的,像这样:

    import SwiftUI
    
    @main
    struct TestApp: App {
        
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    }
    
    class Model: ObservableObject {
        @Published var example: [String] = ["Data 1", "Data 2", "Data 3"]
        @Published var selected: String?
    }
    
    struct ContentView: View {
        @StateObject var data: Model = Model()
    
        var body: some View {
            VStack {
                Button(action: {
                    data.selected = nil
                    data.example.removeAll()
                }) {
                    Text("Empty Example data")
                }
                NavigationView {
                    List {
                        ForEach(data.example, id: \.self) { element in
                            NavigationLink(destination: DestinationView(),
                                           tag: element,
                                           selection: $data.selected) {
                                Text(element)
                            }
                        }
                    }
                    Text("Nothing selected")
                }.environmentObject(data)
            }
        }
    }
    
    struct DestinationView: View {
        @EnvironmentObject var data: Model
        var body: some View {
            Text("\(data.selected ?? "")")
        }
    }
    

    【讨论】:

    • 太好了,谢谢。但是,该解决方案会在单击按钮后导致右窗格为空,而不显示默认的Text("Nothing selected")。有什么办法可以让默认视图Text再次显示?
    猜你喜欢
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    相关资源
    最近更新 更多