[英]SwiftUI: detecting the NavigationView back button press
在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
並不能解決問題,因為在彈出視圖或推送新視圖時會調用它的閉包。
跟進我的評論,我將對showDetails
的 state 的更改做出反應。 不幸的是didSet
似乎沒有用@State
變量觸發。 相反,我們可以使用可觀察視圖 model 來保存 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")
}
}
}
觀察已發布的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?
}
}
}
}
快速的解決方案是創建一個自定義的后退按鈕,因為現在框架沒有這種可能性。
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")
})
}
}
按下后退按鈕后,視圖會將 isPresented 設置為 false,因此您可以在該值上使用觀察者來在按下后退按鈕時觸發代碼。 假設此視圖顯示在導航 controller 中:
struct MyView: View {
@Environment(\.isPresented) var isPresented
var body: some View {
Rectangle().onChange(of: isPresented) { newValue in
if !newValue {
print("detail view is dismissed")
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.