How to remove the default Navigation Bar space in SwiftUI NavigationView
For some reason, SwiftUI requires that you also set .navigationBarTitle
for .navigationBarHidden
to work properly.
NavigationView {
FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
.navigationBarTitle("")
.navigationBarHidden(true)
}
Update
As @Peacemoon pointed out in the comments, the navigation bar remains hidden as you navigate deeper in the navigation stack, regardless of whether or not you set navigationBarHidden
to false
in subsequent views. As I said in the comments, this is either a result of poor implementation on Apple's part or just dreadful documentation (who knows, maybe there is a "correct" way to accomplish this).
Whatever the case, I came up with a workaround that seems to produce the original poster's desired results. I'm hesitant to recommend it because it seems unnecessarily hacky, but without any straightforward way of hiding and unhiding the navigation bar, this is the best I could do.
This example uses three views - View1
has a hidden navigation bar, and View2
and View3
both have visible navigation bars with titles.
struct View1: View {
@State var isNavigationBarHidden: Bool = true
var body: some View {
NavigationView {
ZStack {
Color.red
NavigationLink("View 2", destination: View2(isNavigationBarHidden: self.$isNavigationBarHidden))
}
.navigationBarTitle("Hidden Title")
.navigationBarHidden(self.isNavigationBarHidden)
.onAppear {
self.isNavigationBarHidden = true
}
}
}
}
struct View2: View {
@Binding var isNavigationBarHidden: Bool
var body: some View {
ZStack {
Color.green
NavigationLink("View 3", destination: View3())
}
.navigationBarTitle("Visible Title 1")
.onAppear {
self.isNavigationBarHidden = false
}
}
}
struct View3: View {
var body: some View {
Color.blue
.navigationBarTitle("Visible Title 2")
}
}
Setting navigationBarHidden
to false
on views deeper in the navigation stack doesn't seem to properly override the preference of the view that originally set navigationBarHidden
to true
, so the only workaround I could come up with was using a binding to change the preference of the original view when a new view is pushed onto the navigation stack.
Like I said, this is a hacky solution, but without an official solution from Apple, this is the best that I've been able to come up with.
SwiftUI - Remove extra space in NavigationBar after transitioning back to Home view from subview
Every time you push a new Home
via a NavigationLink
, you're adding another NavigationView
to the hierarchy, since Home
has a NavigationView
in it.
To avoid that, you could separate the NavigationView
out and instead link to View
:
struct Home: View {
var body: some View {
NavigationView {
View1() //<-- Here
}
}
}
struct View1 : View {
@State private var view2 = false
var body: some View {
VStack {
Text("Home View!")
.padding()
NavigationLink(destination: View2(), isActive: $view2) { }
Button {
self.view2 = true
} label: {
Text("Go to next view")
}
}
.navigationTitle("Home")
}
}
struct View2: View {
@State private var home = false
var body: some View {
VStack {
Text("This is View 2")
.padding()
NavigationLink(destination: View1() //<-- Here
.navigationBarBackButtonHidden(true), isActive: $home) { }
Button {
self.home = true
} label: {
Text("Go to Home view")
}
}
.navigationTitle("View 2")
}
}
That being said, I'm a little skeptical of the strategy here. It seems like instead of pushing a new View1
, you might just want to be going back to the existing one. In that case, your code could just look like this:
struct Home: View {
var body: some View {
NavigationView {
View1()
}
}
}
struct View1 : View {
@State private var view2 = false
var body: some View {
VStack {
Text("Home View!")
.padding()
NavigationLink(destination: View2(), isActive: $view2) { }
Button {
self.view2 = true
} label: {
Text("Go to next view")
}
}
.navigationTitle("Home")
}
}
struct View2: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
Text("This is View 2")
.padding()
Button {
presentationMode.wrappedValue.dismiss()
} label: {
Text("Go to Home view")
}
}
.navigationTitle("View 2")
}
}
when placing items in the toolbar, How do you remove the space where a navigation title would go
putting .navigationBarTitleDisplayMode(.inline)
on the VStack fixes this issue. (credit: ChrisR for the comment)
SwiftUI NavigationView remove white space
It looks like your HomeView
/s NavigationView
has .navigationBarTitleDisplayMode(.large)
or automatic, which is by default .large
, but your SettingView
has .navigationBarTitleDisplayMode(.inline)
(taking into account divider below < Setting
), so you see different height of title bars.
Of course it is assumption due not absent of detailed code, but possible solution to make it same would be add explicit mode for ProfileView
, eg:
VStack {
ScrollView(showsIndicators: false) {
}
}.navigationBarTitleDisplayMode(.inline) // << here !!
Hide navigation bar Swiftui
Moving the navigationBarTitle and navigationBarHidden within the NavigationView will remove the sticky header. Here's the code.
import SwiftUI
struct ContentView: View {
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
var body: some View {
NavigationView {
List(months, id: \.self) { month in
NavigationLink(destination: DetailView(month: month)) {
Text(month)
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
//.navigationBarBackButtonHidden(true)
}
}
struct DetailView: View {
let month: String
var body: some View {
Text(month)
}
}
Extra space in the Top of Detail View that won't go away (SwiftUI)
That is the NavigationBar
with a large
style. You can make it smaller by using this modifier:
.navigationBarTitle("Title", displayMode: .inline)
Update due to OP's comment
If you want to keep the large title while expanding the contents, you should consider ignoring the safe area's top
edge:
.edgesIgnoringSafeArea(.top)
Also, you may want to add some padding
s BEFORE ignoring safe area to preserve the inline
navigation size.
Important
Note that all of these modifiers should apply to the destination view.
The
NavigationBar
will stay there and prevent touch events from passing to the views below. You should use.navigationBarHidden(true)
if you really need to get rid of it.
How to get rid of space in nested NavigationView with SwiftUI
Only use NavigationView at the top level, you don't need to add it in every subscreen, just remove it from CalendarList and DateDetails and it will fix your spacing issue
Related Topics
Detect First Launch of iOS App
Alternative to Dtsendsignalflag to Identify Key Events in Instruments
iOS Memory Allocation - How Much Memory Can Be Used in an Application
How to Make a Uilabel Clickable
Xcode Quits Unexpectedly Every Time I Open My Project
Uiscrollview: Paging Horizontally, Scrolling Vertically
Uisearchbar Increases Navigation Bar Height in iOS 11
Uiview Animatewithduration Doesn't Animate Cornerradius Variation
Custom Annotation View for Userlocation Not Moving the Mapview
Swift Different Images For Annotation
Facebook Sdk 3.1 - Error Validating Access Token
Simulate Force Touch/3D Touch on iPhone 6S or iPhone 6S Plus Simulators
Cocoapods - 'Pod Install' Takes Forever
Resize Uiimage to 200X200Pt/Px
What Is the Meaning of the "No Index Path for Table Cell Being Reused" Message in iOS 6/7