【发布时间】:2020-03-06 14:16:13
【问题描述】:
我有一个可以显示为模式的视图,也可以简单地推送到导航堆栈上。当它被按下时,它在左上角有后退按钮,当它显示为模态时,我想添加一个关闭按钮(我的许多测试人员不容易弄清楚他们可以滑下模态并且真的需要一个明确的关闭按钮)。
现在,我有很多问题。
- 如何判断视图是否以模态方式显示?或者,如果它不是导航堆栈上的第一个视图?在 UIKit 中有多种方法可以轻松做到这一点。添加
presentationMode@Environment变量没有帮助,因为它的isPresented值对于推送的屏幕也是如此。我当然可以自己传递一个isModal变量,但似乎很奇怪这是唯一的方法? - 如何有条件地添加前导 navigationBarItem?问题是如果你给
nil,即使是默认的后退按钮也是隐藏的。
将代码复制并粘贴到 Xcode 中并使用:
import SwiftUI
struct ContentView: View {
@State private var showModal = false
var body: some View {
NavigationView {
VStack(spacing: 20) {
Button("Open modally") {
self.showModal = true
}
NavigationLink("Push", destination: DetailView(isModal: false))
}
.navigationBarTitle("Home")
}
.sheet(isPresented: $showModal) {
NavigationView {
DetailView(isModal: true)
}
}
}
}
struct DetailView: View {
@Environment(\.presentationMode) private var presentationMode
let isModal: Bool
var body: some View {
Text("Hello World")
.navigationBarTitle(Text("Detail"), displayMode: .inline)
.navigationBarItems(leading: closeButton, trailing: deleteButton)
}
private var closeButton: some View {
Button(action: { self.presentationMode.wrappedValue.dismiss() }) {
Image(systemName: "xmark")
.frame(height: 36)
}
}
private var deleteButton: some View {
Button(action: { print("DELETE") }) {
Image(systemName: "trash")
.frame(height: 36)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
如果我将closeButton 更改为返回可选的AnyView?,然后在isModal 为假时返回nil,我根本没有返回按钮。我也不能调用navigationBarItems 两次,一次是前导按钮,一次是尾随按钮,因为后一个调用会覆盖第一个调用。我有点卡在这里。
【问题讨论】:
-
关于整个视图层次结构中的跟踪模式,您可以考虑Dismiss a parent modal in SwiftUI from a NavigationView主题中提供的方法
-
请在继续之前,看看为什么在工作表中使用 NavigationView 是错误的想法stackoverflow.com/questions/60468040/… 如果向下滑动不起作用,请添加一些关闭按钮,不要使用导航堆栈
-
我在模式中使用 NavigationView,因为我想在导航栏中显示标题和一些按钮。不是因为我要将辅助屏幕推送到模态的导航堆栈上。对我来说似乎非常好,而不是我想要改变的东西。
-
这种情况,看我的回答