SwiftUI 导航栏不会消失
SwiftUI Navigation Bar doesn't disappear
我有一个 NavigationView
,我在 SplashScreen
中设置了 .navigationBarHidden(true)
。在这里它没有正确显示,但是当我转到下一个屏幕时,会出现 NavigationView
栏。如何正确隐藏导航栏?背景也没有正常显示。
查看
struct EventsScreen: View {
var eventsRepository: EventsRepository
@State
var currentPage: Int = 0
@State
private var searchTerm : String = ""
func getEventSections() -> [EventSection] {
eventsRepository.fetchEventSections()
}
func getViewControllers() -> [UIHostingController<EventFeatureView>] {
return eventsRepository.fetchFeaturedEvents().map({ event in
UIHostingController(rootView: EventFeatureView(event: event))
})
}
var body: some View {
NavigationView {
List {
ZStack(alignment: .top) {
EventViewController(controllers: self.getViewControllers(), currentPage: self.$currentPage)
VStack {
SearchBar(text: $searchTerm)
.padding(EdgeInsets.init(top: 16, leading: 16, bottom: 0, trailing: 16))
HStack {
Spacer()
Chip(text: "Dates", action: {
//TODO filter on dates
})
Chip(text:"Type", action: {
//TODO filter event type
})
Chip(text: "Points", action: {
//TODO filter points
})
Spacer()
}
}
}.listRowInsets(EdgeInsets())
.frame(height: 600)
ForEach(self.getEventSections()) { section in
EventSectionView(eventSection: section)
}
}
}
.background(LinearGradient(gradient: Gradient(colors: [.black, ColorTheme.brandPurple.color]), startPoint: .top, endPoint: .bottom))
.navigationBarTitle(Text("Events"), displayMode: .inline)
.navigationBarHidden(true)
}
}
SDK 是这么说的:
/// Hides the navigation bar for this view.
///
/// This modifier only takes effect when this view is inside of and visible
/// within a `NavigationView`.
///
/// - Parameters:
/// - hidden: A Boolean value that indicates whether to hide the
/// navigation bar.
@available(OSX, unavailable)
public func navigationBarHidden(_ hidden: Bool) -> some View
因此,您必须将其设置为 false
,以便在导航期间 每个 顶部视图显示在 NavigationView
中,否则它会在您观察时显示.
您可以为 NavigationView
中显示的 child View
设置 .navigationBarHidden(true)
。我不确定下一个屏幕 View
是什么样子,但我会尝试以下操作:
struct NextScreen: View {
var body: some View {
Group {
// existing body content
}
.background(LinearGradient(gradient: Gradient(colors: [.black, ColorTheme.brandPurple.color]), startPoint: .top, endPoint: .bottom))
.navigationBarTitle(Text("Next Screen"), displayMode: .inline)
.navigationBarHidden(true)
}
}
Group
是为了防止您的正文内容未全部包含在某种 View
(例如 VStack
、List
等)中.
这样想可能会有所帮助:
NavigationView
通常会从其 child 视图中继承 .navigationBarHidden()
。但是,由于 .navigationBarHidden()
和 .background()
是在 EventsScreen
中的 NavigationView
之外明确定义的,因此它们恰好向下工作并应用于 child 中的视图EventsScreen
(除非这些视图有自己明确定义的属性)。
虽然 NextScreen
视图仍显示在 NavigationView
中,但 NextScreen
已使用其自身的默认属性(如背景颜色)进行初始化。一旦应用程序 navigates/updates 变为 NextScreen
,NextScreen
的属性将优先,包括 .navigationBarHidden(false)
的默认值,并且可能是系统背景颜色。它是关于哪个视图(及其属性)将成为先例,并且 SwiftUI 倾向于优先考虑 children,并从那里扩大(前提是给定的 属性 的范围适用于它的 parent 观看次数)。
所以总而言之,如果您希望它们保持更改状态,则必须在出现在 NavigationView
中的每个视图中显式覆盖这些默认值。
您需要像这样使用您的代码:
var body: some View {
NavigationView {
...
.navigationBarTitle(Text("Events"), displayMode: .inline)
.navigationBarHidden(true)
}
// that means only show one view at a time no matter what device I'm working
.navigationViewStyle(StackNavigationViewStyle())
}
您可以将navigationBarHidden
绑定到变量,这样您就可以在特定条件下更改值。像这样:.navigationBarHidden($onOff)
我有一个 NavigationView
,我在 SplashScreen
中设置了 .navigationBarHidden(true)
。在这里它没有正确显示,但是当我转到下一个屏幕时,会出现 NavigationView
栏。如何正确隐藏导航栏?背景也没有正常显示。
查看
struct EventsScreen: View {
var eventsRepository: EventsRepository
@State
var currentPage: Int = 0
@State
private var searchTerm : String = ""
func getEventSections() -> [EventSection] {
eventsRepository.fetchEventSections()
}
func getViewControllers() -> [UIHostingController<EventFeatureView>] {
return eventsRepository.fetchFeaturedEvents().map({ event in
UIHostingController(rootView: EventFeatureView(event: event))
})
}
var body: some View {
NavigationView {
List {
ZStack(alignment: .top) {
EventViewController(controllers: self.getViewControllers(), currentPage: self.$currentPage)
VStack {
SearchBar(text: $searchTerm)
.padding(EdgeInsets.init(top: 16, leading: 16, bottom: 0, trailing: 16))
HStack {
Spacer()
Chip(text: "Dates", action: {
//TODO filter on dates
})
Chip(text:"Type", action: {
//TODO filter event type
})
Chip(text: "Points", action: {
//TODO filter points
})
Spacer()
}
}
}.listRowInsets(EdgeInsets())
.frame(height: 600)
ForEach(self.getEventSections()) { section in
EventSectionView(eventSection: section)
}
}
}
.background(LinearGradient(gradient: Gradient(colors: [.black, ColorTheme.brandPurple.color]), startPoint: .top, endPoint: .bottom))
.navigationBarTitle(Text("Events"), displayMode: .inline)
.navigationBarHidden(true)
}
}
SDK 是这么说的:
/// Hides the navigation bar for this view. /// /// This modifier only takes effect when this view is inside of and visible /// within a `NavigationView`. /// /// - Parameters: /// - hidden: A Boolean value that indicates whether to hide the /// navigation bar. @available(OSX, unavailable) public func navigationBarHidden(_ hidden: Bool) -> some View
因此,您必须将其设置为 false
,以便在导航期间 每个 顶部视图显示在 NavigationView
中,否则它会在您观察时显示.
您可以为 NavigationView
中显示的 child View
设置 .navigationBarHidden(true)
。我不确定下一个屏幕 View
是什么样子,但我会尝试以下操作:
struct NextScreen: View {
var body: some View {
Group {
// existing body content
}
.background(LinearGradient(gradient: Gradient(colors: [.black, ColorTheme.brandPurple.color]), startPoint: .top, endPoint: .bottom))
.navigationBarTitle(Text("Next Screen"), displayMode: .inline)
.navigationBarHidden(true)
}
}
Group
是为了防止您的正文内容未全部包含在某种 View
(例如 VStack
、List
等)中.
这样想可能会有所帮助:
NavigationView
通常会从其 child 视图中继承 .navigationBarHidden()
。但是,由于 .navigationBarHidden()
和 .background()
是在 EventsScreen
中的 NavigationView
之外明确定义的,因此它们恰好向下工作并应用于 child 中的视图EventsScreen
(除非这些视图有自己明确定义的属性)。
虽然 NextScreen
视图仍显示在 NavigationView
中,但 NextScreen
已使用其自身的默认属性(如背景颜色)进行初始化。一旦应用程序 navigates/updates 变为 NextScreen
,NextScreen
的属性将优先,包括 .navigationBarHidden(false)
的默认值,并且可能是系统背景颜色。它是关于哪个视图(及其属性)将成为先例,并且 SwiftUI 倾向于优先考虑 children,并从那里扩大(前提是给定的 属性 的范围适用于它的 parent 观看次数)。
所以总而言之,如果您希望它们保持更改状态,则必须在出现在 NavigationView
中的每个视图中显式覆盖这些默认值。
您需要像这样使用您的代码:
var body: some View {
NavigationView {
...
.navigationBarTitle(Text("Events"), displayMode: .inline)
.navigationBarHidden(true)
}
// that means only show one view at a time no matter what device I'm working
.navigationViewStyle(StackNavigationViewStyle())
}
您可以将navigationBarHidden
绑定到变量,这样您就可以在特定条件下更改值。像这样:.navigationBarHidden($onOff)