Create a Navigationlink Without Back Button Swiftui

Create a NavigationLink without back button SwiftUI

The right way to get what you want here is to use the presentationMode environment variable:

import SwiftUI

struct View2: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

var body: some View {
VStack {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("POP")
}
}
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
}
}

struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: View2()) {
Text("PUSH")
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

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 disappear back button with navigationLink

In the console, you'll notice this message:

2021-04-27 12:37:36.862733-0700 MyApp[12739:255441] [Assert] displayModeButtonItem is internally managed and not exposed for DoubleColumn style. Returning an empty, disconnected UIBarButtonItem to fulfill the non-null contract.

The default style for NavigationView is usually DefaultNavigationViewStyle, which is really just DoubleColumnNavigationViewStyle. Use StackNavigationViewStyle instead, and it works as expected.

Edit: You are right that StackNavigationViewStyle will break iPad split view. But thankfully, DoubleColumnNavigationViewStyle works fine in iPad and doesn't hide the back button. We can then just use a different NavigationStyle depending on the device, as shown in this answer.

struct ResponsiveNavigationStyle: ViewModifier {
@Environment(\.horizontalSizeClass) var horizontalSizeClass

@ViewBuilder
func body(content: Content) -> some View {
if horizontalSizeClass == .compact { /// iPhone
content.navigationViewStyle(StackNavigationViewStyle())
} else { /// iPad or larger iPhone in landscape
content.navigationViewStyle(DoubleColumnNavigationViewStyle())
}
}
}

struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Hello, world!")
.padding()
NavigationLink(destination: ListView()) {

Image(systemName: "trash")
.font(.largeTitle)
.foregroundColor(.red)
}
}
.navigationBarHidden(true)
.navigationTitle("Image")
}
.modifier(ResponsiveNavigationStyle()) /// here!
}
}

Result:















iPadiPhone
iPad split view working and back button not hiddenBack button also not hidden

How to navigate to a View in SwiftUI without NavigationLink

First of all - congratulations: This is the first such complex code, that flawlessly runs on copy/paste into Xcode ... doesn't happen often :)

To your question:

You almost have it. The only thing is that your productFamilyIsActive is a Bool – that can only hold info on ONE selected NavigationLink, you have 3. But it can if you change it to an optional selection:

class Navigation: ObservableObject {
@Published var productFamilyIsActive : String? = nil // here
}

For that you use a different init on NavigationLink here:

struct ProductFamilyRow: View {

@EnvironmentObject var navigation : Navigation
@State var productFamily : String

var body: some View {
NavigationLink(destination: PartNumberView(productFamily: productFamily),
tag: productFamily, // here
selection: $navigation.productFamilyIsActive) { // and here
Text("\(productFamily)")
}
.isDetailLink(false)
}
}

Lastly you don't set to false but to nil here:

struct HomeButtonView: View {

@EnvironmentObject var navigation : Navigation

var body: some View {
Button(action: {
self.navigation.productFamilyIsActive = nil // here
}, label: {
Image(systemName: "house")
})
.environmentObject(navigation)
}
}

Voila!

How to bind an action to the navigationview back button?

You can't bind directly to the back button, but you can have the navigation link itself be activated based on state, and then listen to the change of the state value like so. Do note that this requires that you manage the setting of state to true (no auto tap like with the default initializer)

struct ContentView: View {
@State private var showingNavView = false
var body: some View {
NavigationView {
List {
NavigationLink("Sub View", isActive: $showingNavView) {
SubView()
}.onTapGesture {
showingNavView = true
}.onChange(of: showingNavView) { newValue in
print(newValue) // Will change to false when back is pressed
}
}
}
}
}
struct SubView: View {
var body: some View {
ZStack {
Color.green
Text("Cool Beans")
}
}
}

Remove space NavigationTitle but not the back button

Standard Back button cannot be shown without navigation bar, because it is navigation item, so part of navigation bar. I assume you just need transparent navigation bar.

Here is demo of possible solution (tested with Xcode 12.1 / iOS 14.1) / images are used for better visibility /

demo

struct ContentView: View {

init() {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
UINavigationBar.appearance().standardAppearance = navBarAppearance
}

var body: some View {

NavigationView {
ZStack {
Image("large_image")
NavigationLink(destination: Image("large_image")) {
Text("Go to details ->")
}
}
.navigationBarItems(trailing: Button(action: {}) {
Image(systemName: "gear")
.font(.title2)
}
)
.navigationBarTitle("", displayMode: .inline)
}.accentColor(.red)
}
}


Related Topics



Leave a reply



Submit