ios - 使用“静态导航栏”关闭视图
问题描述
我创建了一个简单的视图作为导航栏,其中包含一个菜单按钮和一些文本。我将它用作我之外的顶级元素NavigationView
,它允许我在所有进入视图的子页面中保持视图静态。我试图不使用带有导航栏项目的默认导航栏的原因是为了避免在切换视图时伴随淡化动画而出现的解雇/创建。
我现在面临的问题是当我离开父视图时关闭子视图。我可以将按钮从菜单图标更新为后退图标,但不会触发按钮的操作。一直在网上寻找是否有人做过类似的事情但没有运气,我不确定我想要实现的目标是否可能,或者我是否以正确的方式去做。self.presentationMode.wrappedValue.dismiss()
即使在根视图中初始化了标头,是否仍然可以从子视图调用?任何帮助表示赞赏,这是我到目前为止所拥有的:
根视图(View1):
struct View1: View {
@State var showMenuButton: Bool = false
var body: some View {
VStack {
CustomNavigationView(showMenuButton: self.showMenuButton)
NavigationView {
NavigationLink(destination: View2()) {
Text("View 2")
}
.navigationBarTitle("")
.navigationBarHidden(true)
.onDisappear(){
self.showMenuButton = false
}
.onAppear() {
self.showMenuButton = true
}
}
}
}
}
根视图的子视图(View2):
struct View2: View {
var body: some View {
VStack{
Text("This is View 2")
.navigationBarTitle("")
.navigationBarHidden(true)
NavigationLink(destination: View3()) {
Text("View 3")
}
}
}
}
视图 2 (View3) 的子视图:
struct View3: View {
var body: some View {
VStack{
Text("This is View 3")
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
自定义导航视图:
struct CustomNavigationView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var showMenuButton = false
var body: some View {
VStack {
HStack {
if showMenuButton {
Button(action: {
//Do Something
}) {
Image(systemName: "line.horizontal.3")
.foregroundColor(.black)
}
} else {
Button(action: { self.presentationMode.wrappedValue.dismiss()}) {
Image(systemName: "arrow.left")
.foregroundColor(.black)
}
}
Text("Sometext")
}
}
}
}
解决方案
您在第一个视图中使用的环境对象“presentationMode”无法关闭您推送的视图。每个想要被摒弃的观点都必须有自己的对象。第一个视图内的对象不属于任何其他推送的视图。因此,您需要创建视图模型来管理此任务。
这是示例代码。希望这能帮助您解决问题。
class NavigationObserver: ObservableObject {
private var views: [Int:Binding<PresentationMode>] = [:]
private var current: Int = 0
func popView() {
guard let view = views[current] else {
return
}
view.wrappedValue.dismiss()
views[current] = nil
current -= 1
}
func pushView(id: Int, newView: Binding<PresentationMode>) {
guard views[id] == nil else {
return
}
current += 1
views[id] = newView
}
}
struct ContentView: View {
@State var showMenuButton: Bool = false
@ObservedObject var observer = NavigationObserver()
var body: some View {
VStack {
CustomNavigationView(observer: self.observer, showMenuButton: self.showMenuButton)
NavigationView {
NavigationLink(destination: View2(observer: self.observer)) {
Text("View 2")
}
.navigationBarTitle("")
.navigationBarHidden(true)
.onDisappear(){
self.showMenuButton = false
}
.onAppear() {
self.showMenuButton = true
}
}
}
}}
struct View2: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var observer: NavigationObserver
var body: some View {
VStack{
Text("This is View 2")
.navigationBarTitle("")
.navigationBarHidden(true)
NavigationLink(destination: View3(observer: self.observer)) {
Text("View 3")
}
}.onAppear {
self.observer.pushView(id: 1, newView: self.presentationMode)
}
}}
struct View3: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var observer: NavigationObserver
var body: some View {
VStack{
Text("This is View 3")
.navigationBarTitle("")
.navigationBarHidden(true)
}.onAppear
{
self.observer.pushView(id: 2, newView: self.presentationMode)
}
}
}
struct CustomNavigationView: View {
@ObservedObject var observer: NavigationObserver
var showMenuButton = false
var body: some View {
VStack {
HStack {
if showMenuButton {
Button(action: {
//Do Something
}) {
Image(systemName: "line.horizontal.3")
.foregroundColor(.black)
}
} else {
Button(action: {
self.observer.popView()
}) {
Image(systemName: "arrow.left")
.foregroundColor(.black)
}
}
Text("Sometext")
}
}
}
}
谢谢,X_X
推荐阅读
- arrays - 使用 #[!no_std] 通过 FFI 将数组从 C 传递到 Rust
- selenium - 根据月份文本自动化日期选择器
- c# - VS2019 类图:显示字段和方法/构造函数之间的关联
- swift - 不能在 Swift 中将 Int 乘以 2
- php - 在 config/shopify-app.php Laravel 5.8 中访问 Auth::user() 实例
- angular - npm remove material-design-icons 后 Angular App 未构建
- sql-server - 使用 Powershell 创建 SQL TABLE 的函数效果不佳
- python - 如何使用 Scrapy 更快地制作 Selenium driver.get
- html - 将按钮放在 div 的右侧
- python-3.x - 从列表中删除 cv2.KeyPoint 对象