Jer*_*Lee 10 navigation dismiss ios swift swiftui
我要实现的功能。比如,来自 Apple 的“Look up”视图。
我的目标是当表单视图通过导航推送另一个视图时,用户可以点击导航项按钮来关闭表单视图。就像,这个下面的gif。
我尝试实现这个功能。
我发现一个问题是当用户点击“完成”按钮时。该应用程序不会关闭工作表视图。它只会将视图弹出到父视图。就像,这个下面的gif。
这是我的代码。
import SwiftUI
struct ContentView: View {
@State var isShowSheet = false
var body: some View {
Button(action: {
self.isShowSheet.toggle()
}) {
Text("Tap to show the sheet")
}.sheet(isPresented: $isShowSheet) {
NavView()
}
}
}
struct NavView: View {
var body: some View {
NavigationView {
NavigationLink(destination: NavSubView()) {
Text("Enter Sub View")
}
} .navigationViewStyle(StackNavigationViewStyle())
}
}
struct NavSubView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
Text("Hello")
.navigationBarItems(trailing:
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}){
Text("Done")
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
我是如何实现这个功能的?:) 请帮帮我,谢谢。:)
Asp*_*eri 16
由于工作表中的导航可能足够长并且关闭不能在所有导航子视图中,我更喜欢使用环境来仅在需要的地方指定关闭功能,而不是通过所有导航堆栈传递绑定。
这是可能的方法(使用 Xcode 11.2 / iOS 13.2 测试)
1)定义环境键来存储工作表状态
struct ShowingSheetKey: EnvironmentKey {
static let defaultValue: Binding<Bool>? = nil
}
extension EnvironmentValues {
var showingSheet: Binding<Bool>? {
get { self[ShowingSheetKey.self] }
set { self[ShowingSheetKey.self] = newValue }
}
}
Run Code Online (Sandbox Code Playgroud)
2) 将此环境值设置为工作表内容的根目录,以便在声明时可在任何子视图中使用
}.sheet(isPresented: $isShowSheet) {
NavView()
.environment(\.showingSheet, self.$isShowSheet)
}
Run Code Online (Sandbox Code Playgroud)
3)仅在将要使用的子视图中声明和使用环境值
struct NavSubView: View {
@Environment(\.showingSheet) var showingSheet
var body: some View {
Text("Hello")
.navigationBarItems(trailing:
Button("Done") {
self.showingSheet?.wrappedValue = false
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
我从来没有尝试过 SwiftUI,但我来自 UIKit + RxSwift,所以我有点知道绑定是如何工作的。我从 SwiftUI 教程中阅读了很多示例代码,您关闭模态的方式实际上是正确的,但显然不适用于导航堆栈。
我刚刚学到的一种方法是使用@Bindingvar。这可能不是最好的解决方案,但它奏效了!
所以你$isShowSheet的ContentView. 通过NavView在该中声明一个变量将该对象传递给您的结构NavView。
内容视图
.....
}.sheet(isPresented: $isShowSheet) {
NavView(isShowSheet: self.$isShowSheet)
}
Run Code Online (Sandbox Code Playgroud)
导航视图
struct NavView: View {
@Binding var isShowSheet: Bool
var body: some View {
NavigationView {
NavigationLink(destination: NavSubView(isShowSheet: self.$isShowSheet)) {
Text("Enter Sub View")
}
} .navigationViewStyle(StackNavigationViewStyle())
}
}
Run Code Online (Sandbox Code Playgroud)
最后,对你的子视图做同样的事情。
导航子视图
struct NavSubView: View {
@Environment(\.presentationMode) var presentationMode
@Binding var isShowSheet: Bool
var body: some View {
Text("Hello")
.navigationBarItems(trailing:
Button(action: {
//self.presentationMode.projectedValue.wrappedValue.dismiss()
self.isShowSheet = false
}){
Text("Done")
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
现在如您所见,您只需要向该isShowSheet绑定 var -发送一个新信号false。
self.isShowSheet = false
瞧!
| 归档时间: |
|
| 查看次数: |
8017 次 |
| 最近记录: |