Remove text from Back button keeping the icon

IosSwiftXcode

Ios 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.

enter image description here

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

enter image description here

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.

enter image description here

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

> enter image description here

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)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlmiguelvargasfView Question on Stackoverflow
Solution 1 - Iosd9radView Answer on Stackoverflow
Solution 2 - Iosm8labsView Answer on Stackoverflow
Solution 3 - IosiOS LifeeView Answer on Stackoverflow
Solution 4 - IosStefanView Answer on Stackoverflow
Solution 5 - IosMuhammad UmairView Answer on Stackoverflow
Solution 6 - IosPradeep BishnoiView Answer on Stackoverflow
Solution 7 - IosRafiqul HasanView Answer on Stackoverflow
Solution 8 - IosRomanVView Answer on Stackoverflow
Solution 9 - IosLalit KumarView Answer on Stackoverflow
Solution 10 - Iosrmd2View Answer on Stackoverflow
Solution 11 - IosAmalendu KarView Answer on Stackoverflow
Solution 12 - IosBilalReffasView Answer on Stackoverflow
Solution 13 - IosBradleyView Answer on Stackoverflow
Solution 14 - IosPolina HillView Answer on Stackoverflow
Solution 15 - IoskevalView Answer on Stackoverflow
Solution 16 - IosHasyaView Answer on Stackoverflow
Solution 17 - IosGaston GonzalezView Answer on Stackoverflow
Solution 18 - IosolowoAView Answer on Stackoverflow
Solution 19 - IosMax NiagolovView Answer on Stackoverflow
Solution 20 - Iosmossman252View Answer on Stackoverflow
Solution 21 - IosVasily BodnarchukView Answer on Stackoverflow
Solution 22 - IosmrcView Answer on Stackoverflow
Solution 23 - IosTushar RaikwarView Answer on Stackoverflow
Solution 24 - IosRikard PlatusView Answer on Stackoverflow
Solution 25 - IosUnluckyView Answer on Stackoverflow
Solution 26 - IosJiri VolejnikView Answer on Stackoverflow
Solution 27 - IossarunwView Answer on Stackoverflow
Solution 28 - IosImran RasheedView Answer on Stackoverflow
Solution 29 - IosThiago BuenoView Answer on Stackoverflow
Solution 30 - IosÁngel TéllezView Answer on Stackoverflow