SwiftUI如何借助navigationLink隐藏返回按钮

4
我有3个视图。其中一个有NavigationView,第二个有NavigationLink,最后只是一个带有工具栏的子元素。
我的问题是当我在最后一个视图中添加工具栏时,返回按钮会优雅地消失。我该如何解决这个问题? 我的问题的屏幕录制
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello, world!")
                    .padding()
                NavigationLink(destination: ListView()) {
                    
                    Image(systemName: "trash")
                        .font(.largeTitle)
                        .foregroundColor(.red)
                }
            }.navigationBarHidden(true)
            .navigationTitle("Image")
        }
    }
}

import SwiftUI

struct ListView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body: some View {
        VStack {
            List {
                NavigationLink(destination: DetailView()) {
                    Text("Detail")
                }
            }
            
        }.navigationBarTitle(Text("Data"), displayMode: .large)
        .toolbar {
            Button("Save") {
                presentationMode.wrappedValue.dismiss()
            }
        }
    }
}

import SwiftUI

struct DetailView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var body: some View {
        
        VStack {
            Text("DetailView")
                .padding()
        }.navigationBarTitle(Text("Data"), displayMode: .large)
        .toolbar {
            Button("Save") {
                presentationMode.wrappedValue.dismiss()
            }
        }
    }
}
2个回答

4
在控制台中,您会注意到以下消息:

2021-04-27 12:37:36.862733-0700 MyApp[12739:255441] [Assert] displayModeButtonItem是内部管理的,不适用于DoubleColumn样式。返回一个空的、未连接的UIBarButtonItem来满足非null合同。

NavigationView的默认样式通常是DefaultNavigationViewStyle实际上只是DoubleColumnNavigationViewStyle。请改用StackNavigationViewStyle,它可以按预期工作。 编辑: 您是对的,StackNavigationViewStyle会破坏iPad分屏视图。但幸运的是,DoubleColumnNavigationViewStyle在iPad上工作正常,不会隐藏返回按钮。因此,我们可以根据设备使用不同的NavigationStyle,如此答案所示。
struct ResponsiveNavigationStyle: ViewModifier {
    @Environment(\.horizontalSizeClass) var horizontalSizeClass

    @ViewBuilder
    func body(content: Content) -> some View {
        if horizontalSizeClass == .compact { /// iPhone
            content.navigationViewStyle(StackNavigationViewStyle())
        } else { /// iPad or larger iPhone in landscape
            content.navigationViewStyle(DoubleColumnNavigationViewStyle())
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello, world!")
                    .padding()
                NavigationLink(destination: ListView()) {
                    
                    Image(systemName: "trash")
                        .font(.largeTitle)
                        .foregroundColor(.red)
                }
            }
            .navigationBarHidden(true)
            .navigationTitle("Image")
        }
        .modifier(ResponsiveNavigationStyle()) /// here!
    }
}

结果:

iPad iPhone
iPad分割视图工作且返回按钮未隐藏 返回按钮也未隐藏

2
.navigationViewStyle(StackNavigationViewStyle()) 但会破坏iPad分屏视图,因此我认为这不是一个好的解决方案。 - dawis11
1
我喜欢这个答案,@aheze - 谢谢。 (但我已经给自己定了一个任务,定期检查它是否仍然需要!) - Matthew

0

我不知道为什么,但这对我起作用:

.toolbar {
    ToolbarItem(placement: .navigationBarTrailing) { 
        Button {  } label: { } // button to the right
    }
    ToolbarItem(placement: .navigationBarLeading) { 
      Text("") // empty text in left to prevent back button to disappear
    } 
}

我已经尝试用EmptyView()替换空文本,但按钮仍然消失。

顺便说一下:我只在使用iOS 14的设备上遇到了这个问题,但在使用iOS 15的另一个设备上,返回按钮从未消失过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接