SwiftUI - NavigationLink 视图中的 NavigationBar 快速显示然后消失
SwiftUI - NavigationBar in View from NavigationLink quickly showing then disappearing
我有一个 ContentView
包含一个 NavigationView
导致 DestinationView
。我想在 ContentView
中隐藏导航栏,但在 DestinationView
中显示它。为了将它隐藏在 ContentView
中,我将 navigationBarHidden
设置为 true
并给 navigationBarTitle
一个空字符串。
在 DestinationView
中,我将 navigationBarHidden
设置为 false 并将其命名为 "DestinationView".
如果我 运行 项目并点击 NavigationLink
,DestinationView
会显示 NavigationBar
,但会在视图出现后迅速隐藏它。有人可以帮我解决这个问题吗?
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView()) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
}
}
您需要使用变量来实现这一点并将其与您的目的地绑定
struct ContentView: View {
@State var isNavigationBarHidden: Bool = true
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView(isNavigationBarHidden: self.$isNavigationBarHidden)) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarHidden(self.isNavigationBarHidden)
.navigationBarTitle("")
.onAppear {
self.isNavigationBarHidden = true
}
}
}
}
struct DestinationView: View {
@Binding var isNavigationBarHidden: Bool
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.onAppear {
self.isNavigationBarHidden = false
}
}
}
编辑:使用 ,因为它是 更 更清洁的解决方案。
我遇到了这个错误并最终使用 UIViewControllerRepresentable
包装了一个控制器,该控制器在其 viewDidAppear
方法中设置了导航栏隐藏状态:
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView()) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
.background(HorribleHack())
}
}
struct HorribleHack: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> HorribleHackViewController {
HorribleHackViewController()
}
func updateUIViewController(_ uiViewController: HorribleHackViewController, context: Context) {
}
}
class HorribleHackViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
DispatchQueue.main.async {
self.navigationController?.setNavigationBarHidden(false, animated: false)
}
}
}
安全区域布局指南存在问题
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
VStack {
NavigationLink(destination: DestinationView()) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
}.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
VStack {
List {
Text("1")
Text("2")
}
}.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
}
}
快乐编码...
对我来说,通过视图层次结构传递绑定并不是最佳选择,将状态添加到环境变量中更可取。
class SceneState: ObservableObject {
@Published var isNavigationBarHidden = true
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
var sceneState = SceneState()
...
let contentView = ContentView().environmentObject(sceneState)
...
}
struct ContentView: View {
var body: some View {
NavigationView {
View1()
}
}
}
struct View1: View {
@EnvironmentObject var sceneState: SceneState
@State private var showView2: Bool = false
var body: some View {
VStack {
Text("NO nav bar.")
Button("Go to View2") {
self.showView2 = true
}
NavigationLink(destination: View2(), isActive: $showView2, label: {EmptyView()})
}
.navigationBarHidden(self.sceneState.isNavigationBarHidden)
.navigationBarTitle("")
.navigationBarBackButtonHidden(self.sceneState.isNavigationBarHidden)
}
}
struct View2: View {
@EnvironmentObject var sceneState: SceneState
var body: some View {
VStack {
Text("WITH nav bar.")
}
.navigationBarHidden(self.sceneState.isNavigationBarHidden)
.navigationBarTitle("WWDC")
.navigationBarBackButtonHidden(self.sceneState.isNavigationBarHidden)
.onAppear {
self.sceneState.isNavigationBarHidden = false
}
}
}
这个问题实际上有一个非常简单的解决方案。经过多次尝试,我想通了,你必须将 .navigationBarHidden(false)
直接添加到 NavigationLink
内的目标视图,如下所示:
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView()
.navigationBarHidden(false)) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
}
}
会如愿以偿,出现后不会消失。
我 运行 iOS 14 模拟器上的这段代码和导航栏没有隐藏,所以我认为这可能是 iOS 13 的问题。我有一个类似的导致导航栏在 iOS 13.5 模拟器上消失的问题和我的代码在 iOS 14.4 模拟器上运行良好。
我有一个 ContentView
包含一个 NavigationView
导致 DestinationView
。我想在 ContentView
中隐藏导航栏,但在 DestinationView
中显示它。为了将它隐藏在 ContentView
中,我将 navigationBarHidden
设置为 true
并给 navigationBarTitle
一个空字符串。
在 DestinationView
中,我将 navigationBarHidden
设置为 false 并将其命名为 "DestinationView".
如果我 运行 项目并点击 NavigationLink
,DestinationView
会显示 NavigationBar
,但会在视图出现后迅速隐藏它。有人可以帮我解决这个问题吗?
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView()) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
}
}
您需要使用变量来实现这一点并将其与您的目的地绑定
struct ContentView: View {
@State var isNavigationBarHidden: Bool = true
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView(isNavigationBarHidden: self.$isNavigationBarHidden)) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarHidden(self.isNavigationBarHidden)
.navigationBarTitle("")
.onAppear {
self.isNavigationBarHidden = true
}
}
}
}
struct DestinationView: View {
@Binding var isNavigationBarHidden: Bool
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.onAppear {
self.isNavigationBarHidden = false
}
}
}
编辑:使用
我遇到了这个错误并最终使用 UIViewControllerRepresentable
包装了一个控制器,该控制器在其 viewDidAppear
方法中设置了导航栏隐藏状态:
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView()) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
.background(HorribleHack())
}
}
struct HorribleHack: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> HorribleHackViewController {
HorribleHackViewController()
}
func updateUIViewController(_ uiViewController: HorribleHackViewController, context: Context) {
}
}
class HorribleHackViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
DispatchQueue.main.async {
self.navigationController?.setNavigationBarHidden(false, animated: false)
}
}
}
安全区域布局指南存在问题
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
VStack {
NavigationLink(destination: DestinationView()) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
}.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
VStack {
List {
Text("1")
Text("2")
}
}.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
}
}
快乐编码...
对我来说,通过视图层次结构传递绑定并不是最佳选择,将状态添加到环境变量中更可取。
class SceneState: ObservableObject {
@Published var isNavigationBarHidden = true
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
var sceneState = SceneState()
...
let contentView = ContentView().environmentObject(sceneState)
...
}
struct ContentView: View {
var body: some View {
NavigationView {
View1()
}
}
}
struct View1: View {
@EnvironmentObject var sceneState: SceneState
@State private var showView2: Bool = false
var body: some View {
VStack {
Text("NO nav bar.")
Button("Go to View2") {
self.showView2 = true
}
NavigationLink(destination: View2(), isActive: $showView2, label: {EmptyView()})
}
.navigationBarHidden(self.sceneState.isNavigationBarHidden)
.navigationBarTitle("")
.navigationBarBackButtonHidden(self.sceneState.isNavigationBarHidden)
}
}
struct View2: View {
@EnvironmentObject var sceneState: SceneState
var body: some View {
VStack {
Text("WITH nav bar.")
}
.navigationBarHidden(self.sceneState.isNavigationBarHidden)
.navigationBarTitle("WWDC")
.navigationBarBackButtonHidden(self.sceneState.isNavigationBarHidden)
.onAppear {
self.sceneState.isNavigationBarHidden = false
}
}
}
这个问题实际上有一个非常简单的解决方案。经过多次尝试,我想通了,你必须将 .navigationBarHidden(false)
直接添加到 NavigationLink
内的目标视图,如下所示:
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
NavigationLink(destination: DestinationView()
.navigationBarHidden(false)) {
ZStack {
Color.green.frame(width: 200, height: 200)
Text("Tap me")
}
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct DestinationView: View {
var body: some View {
List {
Text("1")
Text("2")
}
.navigationBarTitle("DestinationView")
.navigationBarHidden(false)
}
}
会如愿以偿,出现后不会消失。
我 运行 iOS 14 模拟器上的这段代码和导航栏没有隐藏,所以我认为这可能是 iOS 13 的问题。我有一个类似的导致导航栏在 iOS 13.5 模拟器上消失的问题和我的代码在 iOS 14.4 模拟器上运行良好。