10

In short, I want to do this, but with SwiftUI.

enter image description here

(Home should be removed)

So far, I have not found a way to access the NavigationBarButton directly, and have managed to find the following that appears to be the only way I can find to date for modifying the button:

struct MyList: View {
    var body: some View {
            Text("MyList")
            .navigationBarTitle(Text(verbatim: "MyList"), displayMode: .inline)
            .navigationBarItems(leading: Text("<"))
    }
}

However, I lose the default return image and get an ugly < instead.

enter image description here

CodeBender
  • 35,668
  • 12
  • 125
  • 132

3 Answers3

6

You need to set the title of the view that the back button will pop to:

struct ContentView: View {    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView()) {
                    Text("push view")
                }
            }.navigationBarTitle("", displayMode: .inline)
        }
    }
}

struct DetailView: View {    
    var body: some View {
        Text("Detail View")
    }
}

Alternatively, to conditionally set or unset the title of the source view, depending on the presentation status you can use the code below.

Beware that the isActive parameter has a bug, but that will most likely be solved soon. Here's a reference to the bug mentioned SwiftUI: NavigationDestinationLink deprecated

struct ContentView: View {
    @State private var active: Bool = false

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView(), isActive: $active) {
                    Text("push view")
                }
            }.navigationBarTitle(!active ? "View Title" : "", displayMode: .inline)
        }
    }
}

struct DetailView: View {
    var body: some View {
        Text("Detail View")
    }
}
kontiki
  • 37,663
  • 13
  • 111
  • 125
  • 4
    While this solves the immediate problem, it creates a new one. Now the "source" view controller has no title in the navigation bar. – Ashley Mills Aug 06 '19 at 15:55
  • 1
    Added another alternative. – kontiki Aug 06 '19 at 16:37
  • Thanks @kontiki, this works perfectly, with the exception of the bug you noted. – CodeBender Aug 06 '19 at 17:08
  • doesn't work in 2021. ..."displayMode: .inline" doesn't work, and adding navigationBarTitleDisplayMode(.inline) on a separate line doesn't work. – johnrubythecat Apr 21 '21 at 21:33
  • I found this worked for me, provided I 1) removed the `!` from `!active`, 2) changed the call to `navigationBarTitle()` to `navigationTitle()`, and 3) put the `.inline` specification in its own line of code as in `.navigationBarTitleDisplayMode(.inline)` – bruce1337 Aug 27 '22 at 14:36
1

Instead of messing with the previous screen's title, you can simply add a 'principal' item in the navigation bar, and make it take up so much space that there is no room for the back button text. SwiftUI will automatically continue showing the back button, but hide its text:

.toolbar {
  ToolbarItem(placement: .principal) { Color.clear }
}
Senseful
  • 86,719
  • 67
  • 308
  • 465
-1

Works on iOS 16

Since you can update NavigationItem inside the init of the View. You can solve this in 2 steps:

  1. Get visible View Controller.
// Get Visible ViewController
extension UIApplication {
    
    static var visibleVC: UIViewController? {
        var currentVC = UIApplication.shared.windows.first { $0.isKeyWindow }?.rootViewController
        while let presentedVC = currentVC?.presentedViewController {
            if let navVC = (presentedVC as? UINavigationController)?.viewControllers.last {
                currentVC = navVC
            } else if let tabVC = (presentedVC as? UITabBarController)?.selectedViewController {
                currentVC = tabVC
            } else {
                currentVC = presentedVC
            }
        }
        return currentVC
    }
    
}
  1. Update NavigationItem inside init of the View.
struct YourView: View {
    
    init(hideBackLabel: Bool = true) {
        if hideBackLabel {
            // iOS 14+
            UIApplication.visibleVC?.navigationItem.backButtonDisplayMode = .minimal
            
            // iOS 13-
            let button = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
            UIApplication.visibleVC?.navigationItem.backBarButtonItem = button
        }
    }

}
k-thorat
  • 4,873
  • 1
  • 27
  • 36