Reputation: 36612
In short, I want to do this, but with SwiftUI.
(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.
Upvotes: 12
Views: 10841
Reputation: 711
SwiftUI's toolbar modifier is much more flexible than the navigationBar modifiers. You aren't limited to a string or Text view as a parameter. Use the built-in environment action dismiss instead of the back button. Dynamic capability and works like a charm.
struct MyList: View {
@Environment(\.dismiss) var dismiss
var body: some View {
Text("Hello, World!")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
dismiss()
} label: {
Text("<")
}
}
ToolbarItem(placement: .principal) {
Text("MyList")
}
}
.navigationBarBackButtonHidden(true)
}
}
Upvotes: 0
Reputation: 1606
If you're looking to work with iOS 16 NavigationStack and need to hide the back button title, you can achieve this with a straightforward solution by setting the toolbarRole
to editor
.
.toolbarRole(.editor)
For Example:
struct SecondView: View {
var body: some View {
Text("Hello Second View")
.navigationTitle("Second View")
.toolbarRole(.editor)
}
}
And the output will be like below:
Upvotes: 3
Reputation: 91641
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 }
}
Upvotes: 4
Reputation: 5123
Works on iOS 16
Since you can update NavigationItem inside the init of the View. You can solve this in 2 steps:
// 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
}
}
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
}
}
}
Upvotes: -1
Reputation: 40499
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")
}
}
Upvotes: 7