Hide navigation bar but keep back button - SwiftUI
I seemed to have resolved my problem by following this and using @Environment
So instead of using a NavigationLink
in my final tab like this:
ZStack(alignment: .topLeading) {
Text("Tab1View")
NavigationLink(destination: ProductList()){
Image(systemName: "chevron.backward")
}
}
I am now using a button that dismisses the view like this using @Environment
:
struct Tab1View: View {
@Environment(\.presentationMode) var presentation
var product: ProductModel
var body: some View {
ZStack(alignment: .topLeading) {
Text("Tab1View")
Button(action: {
self.presentation.wrappedValue.dismiss()
}, label: {
Text("PressMe")
})
}
}
}
Doing this allows me to hide the NavigationBar
in the TabView the same way:
.navigationBarTitle("")
.navigationBarHidden(true)
SwiftUi - hide Back button and navigation bar (appears for a fraction of second)
Add the same modifiers also for link destination,
var body: some View {
NavigationView {
NavigationLink(destination: DeferView { WeekView(journey: self.launcher.completeJourney!) }
.navigationBarHidden(true) // here !!
.navigationBarTitle("") // here !!
, isActive: self.$launcher.readyJourney ) { EmptyView () }
.navigationBarHidden(true)
.navigationBarTitle("")
}
}
SwiftUI How To Hide The Navigation Bar While Keeping The Back Button
I think you try to use UIKit logic instead of the SwiftUI one. This is what I would do to hide the navigation bar with a back button on the top leading side of your view.
As for hiding the status bar, I would use .statusBar(hidden: true).
But it seems not to work on iOS14. It may be a bug... You can refer yourself to the Apple documentation on this topic.
struct DetailsView: View {
@Environment(\.presentationMode) var presentation
var test: Int
var body: some View {
ZStack(alignment: .topLeading) {
ScrollView {
Text("More Cool \(test)")
Text("Cool \(test)")
Text("Less Cool \(test)")
}
Button(action: { presentation.wrappedValue.dismiss() }) {
HStack {
Image(systemName: "chevron.left")
.foregroundColor(.blue)
.imageScale(.large)
Text("Back")
.font(.title3)
.foregroundColor(.blue)
}
}
.padding(.leading)
.padding(.top)
}
.navigationTitle(Text(""))
.navigationBarHidden(true)
.statusBar(hidden: true)
}
}
I want to hide the navigation bar and display only the back button in SwiftUI
Here is the way to add custom button instead of navigationBar
struct DestinationView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
VStack(alignment: .center, spacing: 0){
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "backward.fill").padding()
Spacer()
}
Spacer()
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
How to dynamically hide navigation back button in SwiftUI
Here is working solution. Back button cannot be hidden, it is managed by bar and owned by parent view, however it is possible to hide entire navigation bar with below approach.
Tested with Xcode 11.4 / iOS 13.4
struct ParentView: View {
@State var isTimerRunning = false
var body: some View {
NavigationView {
VStack {
NavigationLink("Go", destination: TimerTest(isTimerRunning: $isTimerRunning))
}
.navigationBarHidden(isTimerRunning)
.navigationBarTitle("Main") // << required, at least empty !!
}
}
}
struct TimerTest: View {
@Binding var isTimerRunning: Bool
var body: some View {
Button(action:self.startTimer) {
Text("Start Timer")
}
}
func startTimer()
{
self.isTimerRunning = true
_ = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { timer in
DispatchQueue.main.async { // << required !!
self.isTimerRunning = false
}
}
}
}
Unable to hide navbar back button (SwiftUI)
There should be only one NavigationView
in your root view (first view in hierarchy), so
struct ThirdOnboardingView: View {
var body: some View {
NavigationView{ // remove this one !!
Tested with Xcode 12.1 / iOS 14.1
Remove back button text from navigationbar in SwiftUI
So I actually ended up with the following solution that actually works. I am overwriting the navigation bar items like so
.navigationBarItems(leading:
Image("backButton")
.foregroundColor(.blue)
.onTapGesture {
self.presentationMode.wrappedValue.dismiss()
}
)
The only issue with this was that the back gesture wasn't working so that was solved by actually extending the UINavigationController
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
Now it's looking exactly the way I want it, the solution is kinda hacky... but it works for now, hopefully SwiftUI will mature a little bit so this can be done easier.
Related Topics
Remove Multiple Indices from Array
Using Guard with a Non-Optional Value Assignment
Adding Uibarbutton Item in Swift
How Is a Type-Erased Generic Wrapper Implemented
Swift 3, Xcode 8 Instantiate View Controller Is Not Working
How to Handle Multiple Network Call in Alamofire
Display All Available Wifi Connections with Swift in Os X
At Runtime, How Does Swift Know Which Implementation to Use
In Swift, What Does This Specific Syntax Mean
Scene Created in Sprite Kit Level Editor Is Not Working
How to Resume Audio After Interruption in Swift
Swift: Popover Dismiss Callback
Delete All Characters After a Certain Character from a String in Swift
App Crash on Sign in (Xcode 9.3) Exc_Bad_Access (Code=1, Address=0X1)
How to Restrict the Type That a Function Throws in Swift
Swift 4 Codable - API Provides Sometimes an Int Sometimes a String
Open File Dialog Crashes in Swift
Why Do I Need to Declare an Optional Value as Nil Explicitly in Struct - Swift