Remove text from Back button keeping the icon
IosSwiftXcodeIos Problem Overview
I want to remove the text from the back button, but I want to keep the icon. I have tried
let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton
However, this removes completely the text and the icon.
Ios Solutions
Solution 1 - Ios
I know this already has an answer, but you can also do it in code (in case you're working with nibs)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Add the above in the first view controller.
Note that you need to do this for each view controller that is pushing. So if you have 3 view controllers, and you want to remove the back text from all of them, you'll have to add the line in view controller 1 and 2.
Solution 2 - Ios
The method of @rmd2 is almost right, but instead you should select the navigation bar of the controller to which back button will point to and type " "
in the Back Button field.
Solution 3 - Ios
After Searching a lot I found best and simple solution, this will affect all the viewControllers written in Swift 4.2 and also working in Swift 5
extension UIViewController {
open override func awakeFromNib() {
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}
After iOS 14
extension UIViewController {
open override func awakeAfter(using coder: NSCoder) -> Any? {
navigationItem.backButtonDisplayMode = .minimal // This will help us to remove text
return super.awakeAfter(using: coder)
}
}
Solution 4 - Ios
The text of the back button depends on the title of the master view.
The trick is to clear the title if the master view disappears and set it again if it is shown again:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// needed to clear the text in the back navigation:
self.navigationItem.title = " "
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.title = "My Title"
}
Solution 5 - Ios
If you wanted to remove the title of a back button from a pushed view controller...
let's say a class named SettingsVC is going to push SubSettingsVC then in the subSettingsVC back button will show a title <Settings
so in order to remove the "settings" text from back button and make it something like <
> you've to set backBarButtonItem title in SettingsVC's > viewWillDisappear() method.
Objective-C:
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];
}
Swift:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Solution 6 - Ios
If you want back arrow so following code put into AppDelegate file into didFinishLaunchingWithOptions method.
For Swift
let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)
Solution 7 - Ios
In my case, for custom icon and title this did the trick (Swift 4)
let imgBack = UIImage(named: "ic_back")
navigationController?.navigationBar.backIndicatorImage = imgBack
navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBack
navigationItem.leftItemsSupplementBackButton = true
navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
Solution 8 - Ios
This is working for me
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Solution 9 - Ios
Finally found perfect solution.
Just add one transparent Image and add following code in your AppDelegate.
UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)
Solution 10 - Ios
I solved this problem by adding a " " on the StoryBoard Title of the previous ViewController. Just a space, not empty ;D
Solution 11 - Ios
in swift 4
self.navigationController?.navigationBar.topItem?.title = ""
Solution 12 - Ios
For Swift 4+ put these lines into AppDelegate
at didFinishLaunchingWithOptions
let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
BarButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
Solution 13 - Ios
If you have a ViewControllerA and you want to navigate to the ViewControllerB, in the ViewControllerA, you should set the current navigationItem with a new UIBarButtonItem and the title to a string with blank space before push to another view controller:
Set the title to a string with a blank space, you can't set nil or "" (empty string) because the default value is nil
let backItem = UIBarButtonItem()
backItem.title = " "
navigationItem.backBarButtonItem = backItem
let controllerB = ViewControllerB()
navigationController?.pushViewController(controllerB, animated: true)
Solution 14 - Ios
Put this code in each VC which pushes another one
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Solution 15 - Ios
You can remove text from back button using a delegate method of UINavigationController
.
class CustomNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
}
extension CustomNavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: String(), style: .plain, target: nil, action: nil)
}
}
Solution 16 - Ios
let button: UIButton = UIButton (type: UIButtonType.Custom)
button.setImage(UIImage(named: "imageName"), forState: UIControlState.Normal)
button.addTarget(self, action: "backButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItem = barButton
func backButtonPressed(btn : UIButton) {
// Your code
}
Solution 17 - Ios
To remove from all viewcontrollers in a navigation controller stack:
subclass UINavigationController and add this:
override func show(_ vc: UIViewController, sender: Any?) {
setEmptyBackButton(vc)
super.show(vc, sender: sender)
}
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
setEmptyBackButton(viewController)
super.pushViewController(viewController, animated: animated)
}
func setEmptyBackButton(_ viewController: UIViewController) {
viewController.navigationItem.backBarButtonItem =
UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Solution 18 - Ios
Xcode 10, Swift 4+
Similar answer to the others here but it is worth noting that if the text still isn't cleared, you have to click Space then Enter.
Solution 19 - Ios
Sometimes its not working to change only the title color, in case when the title is long. Because it might shift the navigation bar title to the left. So to prevent it you might need to shift the bar button title horizontally in addition to make it transparent:
let barButtonItemAppearance = UIBarButtonItem.appearance()
barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
barButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
Solution 20 - Ios
This will solve your issue:
import UIKit
extension UINavigationController{
func customizeBackArrow(){
let yourBackImage = UIImage(named: "icon_back_arrow")
self.navigationBar.backIndicatorImage = yourBackImage
self.navigationBar.tintColor = Common.offBlackColor
self.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
navigationItem.leftItemsSupplementBackButton = true
self.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "",
style: .plain, target: self, action: nil)
}
}
Solution 21 - Ios
Details
- Xcode Version 10.2.1 (10E1001), Swift 5
Solution
1. Create custom class of the UINavigationController
import UIKit
class NavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
}
extension NavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if viewController.navigationItemBackButtonTextIsHidden {
viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}
}
2. Add UIViewController extension
import UIKit
extension UIViewController {
@objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}
3. Update your ViewController class
import UIKit
class ViewController: UIViewController {
override var navigationItemBackButtonTextIsHidden: Bool { return true }
}
Full sample
import UIKit
// MARK: - ViewController
class ViewController: UIViewController {
var screenCounter = 1
override func viewDidLoad() {
super.viewDidLoad()
setupNavigationItem()
}
override var navigationItemBackButtonTextIsHidden: Bool { return (screenCounter % 2) == 0 }
}
extension ViewController {
private func setupNavigationItem() {
navigationItem.title = "VC \(screenCounter)"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "push", style: .plain, target: self, action: #selector(pushBarButtonTouchedUpInside))
}
@objc func pushBarButtonTouchedUpInside(button: UIBarButtonItem) {
guard let navigationController = navigationController else { return }
let viewController = ViewController()
viewController.screenCounter = screenCounter + 1
viewController.view.backgroundColor = .white
navigationController.pushViewController(viewController, animated: true)
}
}
// MARK: - NavigationController
class NavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
}
extension NavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if viewController.navigationItemBackButtonTextIsHidden {
viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}
}
// MARK: - UIViewController extension
extension UIViewController {
@objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}
Result
Solution 22 - Ios
For me this did the trick:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
self.navigationItem.title = " "
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.title = "my amazing title"
navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}
Notice that if you only set the title without modifying the backBarButtonItem it will appear to work. But if you try to go back using a gesture and than cancel and stay on the pushed view controller, the back title will come back.
Working in Swift 4
Solution 23 - Ios
You should select the navigation bar of the controller FROM which back button will point to and type " " in the Back Button field.
e.g if you are pushing A controller to B controller, put whitespace in A controller navigation bar.
Solution 24 - Ios
I've tried a couple of answers and I can't get them to work in all cases. So this is a workaround to not affect the title of the navigation bar if it's set.
guard let items = viewController.navigationController?.navigationBar.items else { return }
for item in items {
if item.title == nil {
item.title = ""
}
}
Solution 25 - Ios
One alternative to override all ViewControllers
for me was to extend UINavigationController
and set the backBarButtonItem
of the topViewController
.
Swift 5
on Xcode 11.2.1:
extension UINavigationController {
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let backButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
self.topViewController?.navigationItem.backBarButtonItem = backButton
}
}
Solution 26 - Ios
The easy programmatic way, without unwanted side-effects, is initializing the navigationItem.backBarButtonItem with an empty item in the awakeFromNib method of the source controller (the one you are navigating from):
override func awakeFromNib() {
super.awakeFromNib()
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Note: If you initialized the back button later, like in the viewDidLoad() method, than you would lose swipe-back functionality (swiping from the left edge to the right takes you one step back in the navigation stack).
Then, if you want different back button texts for different destination controllers and if you're using segues, you can set the title in the prepare(for segue:, sender:) method, like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let item = navigationItem.backBarButtonItem {
switch segue.identifier {
case "SceneOne": item.title = "Back"; break
case "SceneTwo": item.title = "Home"; break
case "SceneThree": item.title = nil; break // Use this scene's title
default: item.title = "" // No text
}
}
}
Solution 27 - Ios
The easiest way to do this programmatically is to set backBarButtonItem
from the parent view controller (a controller that calls push).
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
navigationItem.backBarButtonItem = backBarButtonItem
}
}
More detail here https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/
Solution 28 - Ios
Swift 5 Version remove back button title and set custom Image ios 13.0+
let backButtonAppearance = UIBarButtonItemAppearance(style: .plain)
backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.backButtonAppearance = backButtonAppearance
navigationBarAppearance.setBackIndicatorImage(#imageLiteral(resourceName: "back"), transitionMaskImage: #imageLiteral(resourceName: "back"))
UINavigationBar.appearance().standardAppearance = navigationBarAppearance
Add this code in App delegate didFinishLaucnh
Solution 29 - Ios
In Xcode 9.2 with Swift, it worked like this:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Solution 30 - Ios
For the case where we have not control at all of the previous view controller (i.e. if we are working in a framework), we can delete the title of the back button as follow:
// For iOS 10
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = String()
// For iOS 11
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = nil
What it does is to navigate to the last item of the navigation's stack and delete its back title. Make sure to save the original one when our view controller will appear:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
originalBackButtonTitle = navigationController?.navigationBar.items?.last?.backBarButtonItem?.title
// Delete title somewhere here...
}
and then reassign it, in order to not disrupt any part of the app:
override func viewWillDisappear(_ animated: Bool) {
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = originalBackButtonTitle
super.viewWillDisappear(animated)
}