单击后退按钮并更新状态数据后,swiftui 子视图重新出现

swiftui subview reappear after click the back button and update state data

非常奇怪的行为。

单击子页面 (Subview) 上的后退按钮 return 返回主页面 (ContentView)。但是,子页面(Subview)会自动再次打开。为什么?

import SwiftUI

struct ContentView: View {
    @State var things: [String] = []
    @State var count: Int = 0
    
    var body: some View {
        NavigationView{
            List {
                ForEach(things.indices, id: \.self) { index in
                    Text(things[index])
                }
            }
            .onAppear {
                update()
            }
           
            .navigationTitle("a")
            .toolbar{
                NavigationLink(destination: Subview(count: $count), label: {
                    Text("sub")
                })
            }
        }
        
    }
    
    func update() {
        things = []
        for i in 0...count {
            things.append(String(i))
        }
    }
}

struct Subview: View {
    var count : Binding<Int>

    var body: some View {
        Text("sub")
            .onAppear {
                count.wrappedValue += 1
            }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

将“onAppear{...}”放在 NavigationView 而不是列表上,如下所示:

struct ContentView: View {
    @State var things: [String] = []
    @State var count: Int = 0
    
    var body: some View {
        NavigationView{
            List {
                ForEach(things.indices, id: \.self) { index in
                    Text(things[index])
                }
            }
            .navigationTitle("a")
            .toolbar{
                NavigationLink(destination: Subview(count: $count), label: {
                    Text("sub")
                })
            }
        }
        .onAppear {   // <---
            update()
        }
    }

NavigationLink 应始终位于 NavigationView 内。如果将其放在工具栏或其他地方,您可能 运行 会遇到奇怪的问题。

而是使用 init(destination:isActive:label:) 初始值设定项。然后设置 presentingNextPage 属性 到 true 当你想显示下一页时。

struct ContentView: View {
    @State var things: [String] = []
    @State var count: Int = 0
    @State var presentingNextPage = false
    
    var body: some View {
        NavigationView {
            
            List {
                ForEach(things.indices, id: \.self) { index in
                    Text(things[index])
                }
                
                /// placeholder navigation link
                NavigationLink(destination: Subview(count: $count), isActive: $presentingNextPage) {
                    EmptyView()
                }
            }
            .onAppear {
                self.update()
            }
            .navigationTitle("a")
            .toolbar{
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("sub") {
                        presentingNextPage = true /// set to true
                    }
                }
                
            }
        }
    }
    
    func update() {
        things = []
        for i in 0...count {
            things.append(String(i))
        }
    }
}

结果: