在 NavigationView 中清除 SwiftUI 列表未正确返回默认值

Posted

技术标签:

【中文标题】在 NavigationView 中清除 SwiftUI 列表未正确返回默认值【英文标题】:Clear SwiftUI list in NavigationView does not properly go back to default 【发布时间】: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") 正在加载。

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

【问题讨论】:

【参考方案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再次显示?

以上是关于在 NavigationView 中清除 SwiftUI 列表未正确返回默认值的主要内容,如果未能解决你的问题,请参考以下文章

swift 在swif打开网址

DrawerLayout 和 NavigationView 的使用

如何在 NavigationView 中获取菜单项?

在 NavigationLink 的嵌套 NavigationView 中列出核心数据对象的正确方法

如何在 SwiftUI 中隐藏 NavigationView Bar

SwiftUI 如何在多级 NavigationView 中停止 List 的动画