Hiding the back button's text in SwiftUI
Hiding it with navigationBarBackButtonHidden also costs you the swipe-back gesture and the long-press stack. Adjusting UINavigationBar's appearance is the safer route.
- Published
This article is also published elsewhere. https://iganin.hatenablog.com/entry/2024/02/26/201210
Originally written in Japanese. This is a translation of the same piece.
This feels like well-trodden ground, but I looked into it again, so here are my notes.
TL;DR
- You can do it by adjusting
UINavigationBar’s appearance - Setting
navigationBarBackButtonHiddenand adding a navigation item tonavigationBarLeadingalso works, but you lose the following:- Navigating back to the previous screen with the swipe gesture
- Long-pressing the back button to show the stack and jump to a screen from it
Environment
Verified on:
- iOS 17.x
- Xcode 15.2
UIKit
First, how to do it in UIKit. This one is very easy: set navigationItem.backButtonDisplayMode to
minimal. It requires iOS 14 or later, but these days that deployment target is usually already met.
backButtonDisplayMode | Apple Developer Documentation
SwiftUI
Now for SwiftUI.
Adjusting UINavigationBar’s appearance
This is probably the soundest approach. The following hides the back button’s text:
appearance.backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]
With this approach you keep the default behaviours that the alternative below disables:
- Navigating between screens with the swipe gesture
- Long-pressing to show the stack and navigate to a chosen screen
ToolbarItem(placement: .navigationBarLeading)
Hide the back button with navigationBarBackButtonHidden() and place your own back button using
ToolbarItem(placement: .navigationBarLeading). Writing a ViewModifier like the following makes it much
less work to apply.
struct MinimalNavigationBarBackButton: ViewModifier {
@Environment(\.dismiss) var dismiss
public func body(content: Content) -> some View {
content
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
dismiss()
} label: {
Image(systemName: "chevron.backward")
}
.foregroundStyle(Color.black)
}
}
}
}
It is the intuitive approach, but it disables these defaults:
- A. Navigating back to the previous screen with a swipe
- B. Long-pressing the back button to show the stack and navigate to a chosen entry
A can be implemented by adjusting UINavigationController, but applying it globally means you can swipe
back even where the back button is hidden, so it needs some control. B is probably implementable too, but
looks like more effort.
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
Other options
These are worth considering as well, though they look likely to change behaviour beyond the back button, so that would need thinking through:
- Setting the user’s
navigationTitleto an empty string at the same time as the transition - Specifying
editorfortoolbarRole
Reference
- backButtonDisplayMode | Apple Developer Documentation
- How to hide the navigation bar back button text in SwiftUI and UIKit (Japanese)
- How to remove Back button title in SwiftUI | Sarunw
- Hiding the navigation bar back button text everywhere via Appearance on iOS 15 and later #Swift - Qiita (Japanese)