SwiftUI:检测NavigationView后退按钮是否按下

时间:2020-05-21 09:03:41

标签: ios swift swiftui

SwiftUI中,我找不到一种方法可以检测到当我在这段代码中的DetailView1内部时,用户何时单击导航视图的默认后退按钮:

struct RootView: View {
    @State private var showDetails: Bool = false
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView1(), isActive: $showDetails) {
                    Text("show DetailView1")
                }
            }
            .navigationBarTitle("RootView")
        }
    }
}

struct DetailView1: View {
    @State private var showDetails: Bool = false
    var body: some View {
        NavigationLink(destination: DetailView2(), isActive: $showDetails) {
            Text("show DetailView2")
        }
        .navigationBarTitle("DetailView1")
    }
}

struct DetailView2: View {
    var body: some View {
        Text("")
            .navigationBarTitle("DetailView2")
    }
}

使用.onDisappear不能解决问题,因为弹出视图或推送新视图时将调用其关闭。

3 个答案:

答案 0 :(得分:2)

快速的解决方案是创建一个自定义后退按钮,因为目前该框架还没有这种可能性。

struct DetailView : View {

    @Environment(\.presentationMode) var mode: Binding<PresentationMode>

    var body : some View {
        Text("Detail View")
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: Button(action : {
                self.mode.wrappedValue.dismiss()
            }){
                Image(systemName: "arrow.left")
            })
    }
}

答案 1 :(得分:1)

在评论之后,我将对showDetails的状态变化做出反应。不幸的是didSet似乎没有被@State变量触发。相反,我们可以使用可观察的视图模型来保存状态,这确实使我们能够使用didSet截取更改。

struct RootView: View {
    class ViewModel: ObservableObject {
        @Published var showDetails = false {
            didSet {
                debugPrint(showDetails)
                // Maybe do something here?
            }
        }
    }
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView1(), isActive: $viewModel.showDetails) {
                    Text("show DetailView1")
                }
            }
            .navigationBarTitle("RootView")
        }
    }
}

答案 2 :(得分:0)

观察发布的showDetails属性的一种更好的方法(SwiftUI-ier?):

struct RootView: View {
    class ViewModel: ObservableObject {
        @Published var showDetails = false
    }
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView1(), isActive: $viewModel.showDetails) {
                    Text("show DetailView1")
                }
            }
            .navigationBarTitle("RootView")
            .onReceive(self.viewModel.$showDetails) { isShowing in
                debugPrint(isShowing)
                // Maybe do something here?
            }
        }
    }
}