Navigation Link in bar Items goes back to top of NavigationView
Put navigation link into body of navigation view (bar is not in navigation view)
So here is possible approach
struct TestView: View {
@State private var isActive = false
var body: some View {
VStack {
Text("View 2")
}
.background(
NavigationLink(destination: Text("View 3"), isActive: $isActive,
label: { EmptyView() })
)
.navigationBarItems(trailing:
Button("Navigate", action: { self.isActive = true }))
}
}
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")
}
}
SwiftUi Navigation Bar Button disappears after entering the third View (Controller)
I found the Problem!
The .toolbar modifier on the NavigationView hides the Backbutton in a Buggy way!
Custom back button for NavigationView's navigation bar in SwiftUI
TL;DR
Use this to transition to your view:
NavigationLink(destination: SampleDetails()) {}
Add this to the view itself:
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
Then, in a button action or something, dismiss the view:
presentationMode.wrappedValue.dismiss()
Full code
From a parent, navigate using NavigationLink
NavigationLink(destination: SampleDetails()) {}
In DetailsView hide navigationBarBackButton
and set custom back button to leading navigationBarItem
,
struct SampleDetails: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var btnBack : some View { Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image("ic_back") // set image here
.aspectRatio(contentMode: .fit)
.foregroundColor(.white)
Text("Go back")
}
}
}
var body: some View {
List {
Text("sample code")
}
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: btnBack)
}
}
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.
ios15 half-swiping back while hiding the navigation bar leaves a top empty space - SwiftUI
It's some weird hackery, but I was able to "fix" it by using .navigationViewStyle(.stack)
on NavigationView
.
If you are interested, btw, the white space was navigation bar and large navigation title. A useful thing in debugging this kind of stuff is the "Debug View Hierarchy" button.
It's definitely a hack, but you could try submitting a bug report to Apple anyway.
Related Topics
How to Draw a Line Between Two Points Over an Image in Swift 3
"The Requested Snapshot Version Is Too Old." Error in Firestore
Swift System Version Checking on Ubuntu
Convert/Wrap Swift Struct as Nsvalue for Caanimation Purposes
Different UIfont Sizes for Different iOS Devices in Swift
Stored Variable of Self Type (Especially When Subclassing)
Cannot Decode Object of Class (Ampathpopupbutton)'
Cannot Get Newpassword to Generate Strong Password and Autofill
How to Unwrap Optional<Optional<T>> in Swift 1.2
Preferredstatusbarupdateanimation Being Ignored
Weak Reference to Closure in Swift
Does Swift Allow Code Blocks Without Conditions/Loops to Reduce Local Variable Scope
Why Is The Leading Swipe Action Also Duplicated as a Trailing Action
Advantage of Key-Value Coding in Swift 4
How to Condense Unwrapping Multiple Optionals in Swift
Swiftui: UIimage (Qrcode) Does Not Load After Calling Function