Ios SwiftUI:检测NavigationView后退按钮按下

Ios SwiftUI:检测NavigationView后退按钮按下,ios,swift,swiftui,Ios,Swift,Swiftui,在SwiftUI中,当我在以下代码中的DetailView1中时,我找不到一种方法来检测用户何时点击导航视图的默认后退按钮: struct RootView: View { @State private var showDetails: Bool = false var body: some View { NavigationView { VStack { NavigationLink(destination

在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并不能解决问题,因为在弹出视图或按下新视图时会调用它的闭包。

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

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")
            })
    }
}

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

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")
            })
    }
}

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


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


一个更好更快的?观察已发布showDetails属性的方式:

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?
            }
        }
    }
}

一个更好更快的?观察已发布showDetails属性的方式:

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?
            }
        }
    }
}

检测到它后,您想做什么?当用户点击后退按钮时,您的DetailView1视图将被取消,您的showDetails状态变量将重置为false–可能这就是您要查找的密钥?showDetails在之后变回false。onDisappear,而不是之前,因此它不能用于早期后退按钮点击检测。以防万一。你检测到它后想做什么?当用户点击后退按钮时,您的DetailView1视图将被取消,您的showDetails状态变量将重置为false–可能这就是您要查找的密钥?showDetails在之后变回false。onDisappear,而不是之前,因此它不能用于早期后退按钮点击检测。以防万一。在这两种情况下,onReceive闭包都是用isShowing=false调用的:1当我将视图弹出到根视图时。2当我转到DetailView2时。因此,此解决方案无法解决问题。在这两种情况下,调用onReceive闭包时都使用isShowing=false:1当我将视图弹出到根视图时。2当我转到DetailView2时。所以这个解决方案并不能解决问题。我用这种方式确认。当用户按下后退按钮时,我想保存一些表单值。这种方法很好用。我只想稍微更新一下设计的东西。使用V形.left,而不是箭头.left符号HStack{ImagesystemName:chevron.left TextBack.font.body}`我以这种方式确认。当用户按下后退按钮时,我想保存一些表单值。这种方法很好用。我只想稍微更新一下设计的东西。使用V形.left,而不是箭头.left符号HStack{ImagesystemName:chevron.left TextBack.font.body}`