I was having this issue and I've tried a lot of solutions that was proposed by some kind people here in the following topic:
Swift - How to hide back button in navigation item
I created a ViewController class:
import SwiftUI
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setHidesBackButton(true, animated: true)
self.navigationController?.navigationBar.isHidden = true
//self.navigationItem.backButtonTitle = "hohoho"
self.navigationItem.leftBarButtonItem = nil
self.navigationItem.hidesBackButton = true
//UINavigationBar.appearance().isHidden = true
//navigationItem.backBarButtonItem = UIBarButtonItem(title: "Home/Return or nohing", style: .bordered, target: nil, action: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.setHidesBackButton(true, animated: true)
self.navigationController?.navigationBar.isHidden = true
//self.navigationItem.backButtonTitle = "hohoho"
self.navigationItem.leftBarButtonItem = nil
self.navigationItem.hidesBackButton = true
//UINavigationBar.appearance().isHidden = true
//navigationItem.backBarButtonItem = UIBarButtonItem(title: "Home/Return or nohing", style: .bordered, target: nil, action: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationItem.setHidesBackButton(true, animated: true)
self.navigationController?.navigationBar.isHidden = true
//self.navigationItem.backButtonTitle = "hohoho"
self.navigationItem.leftBarButtonItem = nil
self.navigationItem.hidesBackButton = true
//UINavigationBar.appearance().isHidden = true
//navigationItem.backBarButtonItem = UIBarButtonItem(title: "Home/Return or nohing", style: .bordered, target: nil, action: nil)
}
}
and AS you can see in the above code I tried every single way with no change - back button still appear - then I try to make simple change like change the text of the back button or the shape and also there is no result!!
Am I do something wrong :( Because I feel like the whole class is not active for my view
Do I need to create an object of ViewController or something like that? Because I just wrote the mentioned code about my view code.
MY GOAL: I just want to move from view to another with no back button if there is another way I wouldn't mind to do it.
PPLLLSSSS HELPP ME Guys I'm so tired, I'll work on another things until find a solution for that and I'm sure there is a lot of people who want a solution for that issue.
Once I find the solution I'll share it with you guys :) Best Wishes and Regards
You just have to add the below code in the ViewController where you want to hide the backbutton.
navigationItem.setHidesBackButton(true, animated: true)
Segue from viewController to viewController2 and name the segue testSegue. This should work.
I had the exact same problem and the only solution that worked was adding
.navigationBarBackButtonHidden(true) in my SwiftUI view
I've a NavigationViewController which segues to a TabbedBarController. I don't want to show the back button on the TabbedBarController.
I've tried both these code snippets in Swift , neither works,
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.hidesBackButton = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.hidesBackButton = true
}
Here's a snap shot,
Here's the tabbed bar view controller,
How can I hide the back button on the Tabbed bar view controller. How can I hide the back button on my tabbed bar controller?
There are quite many ways to do what you want, but what I'm 99.9% sure that would work is that you can add a barButton in your leftBarButtonItems to replace the default backButton of your navigationController:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.leftBarButtonItems = [UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)]
}
Also, when overriding any lifecycle methods of a controller, you might not want to miss anything from the parent class, so don't forget to call its super equivalent like super.viewWillAppear(animated)
I hope this helps!
EDIT: Two ways to do what you want in tabBarController and since I can already picture the flow of your project.
Put the code inside the viewWillAppear of your tabBarController. This means that you might need to subclass the UITabBarController. So it should be like this:
class MyTabBarController: UITabBarController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.leftBarButtonItems = [UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)]
}
}
You should present modally your tabBarController (this is more ideal).
I want to be able to change the action of the back bar button item on a specific UIViewController in my navigation controller so that it pops to the root view controller. I've tried the following but they don't work:
let backButton = UIBarButtonItem(title: nil, style: .plain, target: self, action: #selector(back))
self.navigationItem.backBarButtonItem = backButton
and
self.navigationItem.backBarButtonItem?.action = #selector(back)
Any suggestions?
You should use self.navigationItem.leftBarButtonItem = backButton
Good luck
First of all backBarButtonItem action not works because you can only change back button title,take a look question about it here.
Solution
In ViewController from which you want to pop to root ViewController you need to set as a delegate of UINavigationControllerDelegate
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
}
and implement UINavigationControllerDelegate this method`
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
if viewController.isKind(of:PreviousViewController.self) {
navigationController.popToRootViewController(animated: animated)
}
}
If my answer not fit your needs you can check similar question here.
To keep the same look and feel of the back button but change the action, see the ViewWillDisappear answer to the question regarding, "Execute action when back bar button of UINavigationController is pressed" Execute action when back bar button of UINavigationController is pressed
This is your solution, just need to set target and selector, nothing more.
private func setNavBar() {
let item = navigationItem.backBarButtonItem
item?.target = self
item?.action = #selector(self.donePressed)
navigationItem.leftBarButtonItem = item
}
#objc private func donePressed() {
self.dismiss(animated: true, completion: nil)
}
How do I set a custom image to all back buttons of view controllers pushed in a UINavigationController?
My issues are:
must look like leftBarButtonItem, position-wise (because the backBarButtonItem itself is too glued to the left and I can't seem to change it's horizontal alignment).
has to be on all back actions (instead of manually setting on each view controller).
having a method setCustomBackButton and calling it on each view controller is also not an option, I'm looking for something like UINavigationBar.appearance(), i.e., throughout the app.
Something like this:
But with the back action working without me manually setting the selector on each view controller.
UPDATE: In response to Joe's solution, I'm getting that error:
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "backArrow")
See Here: https://www.raywenderlich.com/108766/uiappearance-tutorial
Below answer based on the following OP answers:
Custom Back Button With Image and How to remove all navigationbar back button title
Try below code in didFinishLaunchingWithOptions method in AppDelegate.
To setting up a custom back button:
let backArrowImage = UIImage(named: "back") // set your back button image here
let renderedImage = backArrowImage?.withRenderingMode(.alwaysOriginal)
UINavigationBar.appearance().backIndicatorImage = renderedImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = renderedImage
To hide a back button title:
let barAppearace = UIBarButtonItem.appearance()
barAppearace.setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), for:UIBarMetrics.default)
Output: Updated
Update:
You need to add the following code to your More Information viewController to keep the title position.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
You can create your own subclass of UINavigationController and change the button inside the navigationController(_:willShow:animated:) delegate method as follows:
class MyNavigationController: UINavigationController, UINavigationControllerDelegate, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
interactivePopGestureRecognizer?.delegate = self
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if viewController != self.viewControllers.first { // don't add button to rootViewController
let backButton = UIBarButtonItem(image: UIImage(named: "backArrow"), style: .plain, target: self, action: #selector(popViewController(animated:)) )
viewController.navigationItem.leftBarButtonItem = backButton
}
}
}
Theoretically the above delegate method could live anywhere, but this way its logical and easy to select where you want to have this functionality.
Also don't forget to set the interactivePopGestureRecognizer delegate for not loosing the edge swipe gesture to go back (this somehow breaks when setting a new leftBarButtonItem).
The above method could be further improved by keeping track of which view controllers were already shown and then only replace the leftBarButtonItem on new ones (right now it also replaces it when going back/popping to an already shown view controller).
Try this Swift 4.2
extension YouFirstViewController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if !(viewController is YouFirstViewController) {
let backButton = UIBarButtonItem(image: UIImage(named: "icnBack"), style: .plain, target: self, action: #selector(popview))
viewController.navigationItem.leftBarButtonItem = backButton
}
}
#objc func popview() {
navigationController?.popViewController(animated: true)
}
}
onYouFirstViewController
class YouFirstViewController: UIViewcontroller {
override func viewDidLoad() {
self.navigationController?.delegate = self
}
}
How do you remove the back button text.
Current back button:
< Back
Desired back button:
< AnythingElse
None of these have worked:
self.navigationItem.backBarButtonItem?.title = "Back"
self.backItem?.title = ""
self.navigationController?.navigationBar.backItem?.title = ""
self.navigationItem.backBarButtonItem?.title = ""
self.navigationController?.navigationItem.backBarButtonItem?.title="Back"
self.navigationController?.navigationBar.backItem?.title = ""
self.navigationController?.navigationItem.backBarButtonItem?.title
The back button belongs to the previous view controller, not the one currently presented on screen.
To modify the back button you should update it before pushing, on the view controller that initiated the segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let backItem = UIBarButtonItem()
backItem.title = "Something Else"
navigationItem.backBarButtonItem = backItem // This will show in the next view controller being pushed
}
Swift 3, 4 & 5:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let backItem = UIBarButtonItem()
backItem.title = "Something Else"
navigationItem.backBarButtonItem = backItem // This will show in the next view controller being pushed
}
OR
// in your viewDidLoad or viewWillAppear
navigationItem.backBarButtonItem = UIBarButtonItem(
title: "Something Else", style: .plain, target: nil, action: nil)
You can do it from interface builder as follows:
click on the navigation item of previous view controller
from the attributes inspector set the back button text to whatever you want. Thats it!!
You can put this 3 line of code in the ViewController you want to change the back button title.
In your override func viewDidLoad() {}.
let backButton = UIBarButtonItem()
backButton.title = "My Back Button Title"
self.navigationController?.navigationBar.topItem?.backBarButtonItem = backButton
Back-button text is taken from parent view-controller's navigation item title. So whatever you set on previous view-controller's navigation item title, will be shown on current view controller's back button text.
You can just put "" as navigation item title in parent view-controller's viewWillAppear method.
self.navigationItem.title = ""
Another way is to put
self.navigationController?.navigationBar.topItem?.title = ""
in current view controller's viewWillAppear method. This one will cause some other problem if navigation stack is too nested.
If you are using xib file for view controller then do this in your view controller class.
class AboutUsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
edgesForExtendedLayout = []
setUpNavBar()
}
func setUpNavBar(){
//For title in navigation bar
self.navigationController?.view.backgroundColor = UIColor.white
self.navigationController?.view.tintColor = UIColor.orange
self.navigationItem.title = "About Us"
//For back button in navigation bar
let backButton = UIBarButtonItem()
backButton.title = "Back"
self.navigationController?.navigationBar.topItem?.backBarButtonItem = backButton
}
}
The result will be:
I do not know where you have used your methods that you put on your question but I could get the desired result if I use, on my ViewController class (in which I want to change the back button), on viewDidLoad() function, the following line:
self.navigationController?.navigationBar.backItem?.title = "Anything Else"
The result will be:
Before
After
The back button belongs to the previous view controller, not the one currently presented on screen.
To modify the back button you should update it before pushing, add viewdidload :
Swift 4:
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
You can just modify the NavigationItem in the storyboard
In the Back Button add a space and press Enter.
Note: Do this in the previous VC.
This should work:
override func viewDidLoad() {
super.viewDidLoad()
var button = UIBarButtonItem(title: "YourTitle", style: UIBarButtonItemStyle.Bordered, target: self, action: "goBack")
self.navigationItem.backBarButtonItem = button
}
func goBack()
{
self.navigationController?.popViewControllerAnimated(true)
}
Although it is not recommended since this actually replaces the backButton and it also removed the back arrow and the swipe gesture.
Swift 4.2
If you want to change the navigation bar back button item text, put this in viewDidLoad of the controller BEFORE the one where the back button shows, NOT on the view controller where the back button is visible.
let backButton = UIBarButtonItem()
backButton.title = "New Back Button Text"
self.navigationController?.navigationBar.topItem?.backBarButtonItem = backButton
If you want to change the current navigation bar title text use the code below (note that this becomes the default back text for the NEXT view pushed onto the navigation controller, but this default back text can be overridden by the code above)
self.title = "Navigation Bar Title"
Swift 4 - Configure the back button before pushing any view controllers
// if you want to remove the text
navigationItem.backBarButtonItem = UIBarButtonItem()
// if you want to modify the text to "back"
navigationItem.backBarButtonItem = UIBarButtonItem(title: "back", style: .plain, target: nil, action: nil)
There are two ways.
1.In the previousViewController.viewDidLoad()
let backBarBtnItem = UIBarButtonItem()
backBarBtnItem.title = "back"
navigationItem.backBarButtonItem = backBarBtnItem
2.In the currentViewController.viewDidAppear()
let backBarBtnItem = UIBarButtonItem()
backBarBtnItem.title = "back"
navigationController?.navigationBar.backItem?.backBarButtonItem = backBarBtnItem
Reason : the backButton comes from navigationBar.backItem.backBarButtonItem,so the first way is obvious.In currentViewController.viewDidLoad(),we can't obtain the reference of backItem,because in viewDidAppear(),the navigationBar pushed navigationView on its stack.so we can make changes to the backItem in currentViewController.viewDidAppear()
For more details,you can see Document:UINavigationBar
Back button text and color text:
navigationController?.navigationBar.tintColor = .red
navigationController?.navigationBar.topItem?.backButtonTitle = "Hi"
In the viewDidLoad method of the presenting controller add:
// hide navigation bar title in the next controller
let backButton = UIBarButtonItem(title: "", style:.Plain, target: nil, action: nil)
navigationItem.backBarButtonItem = backButton
although these answers fix the problem but this could be some useful
class MainNavigatioController: UINavigationController {
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
// first
let backItem = UIBarButtonItem()
backItem.title = "رجوع"
self.viewControllers.last?.navigationItem.backBarButtonItem = backItem
// then
super.pushViewController(viewController, animated: animated)
}
}
Swift 4
While the previous saying to prepare for segue is correct and its true the back button belongs to the previous VC, its just adding a bunch more unnecessary code.
The best thing to do is set the title of the current VC in viewDidLoad and it'll automatically set the back button title correctly on the next VC. This line worked for me
navigationController?.navigationBar.topItem?.title = "Title"
It works for me. Swift 5
navigationItem.backButtonTitle = ""
This works for Swift 5:
self.navigationItem.backBarButtonItem?.title = ""
Please note it will be effective for the next pushed view controller not the current one on the display, that's why it's very confusing!
Also, check the storyboard and select the navigation item of the previous view controller then type something in the Back Button (Inspector).
Try this... it will work ....
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
self.title = ""
}
The above code will hide the text and show only the back arrow on navigation bar.
Swift 4
In my case the solution was to clear the navigation item of the Master View Controller before move to the Child View Controller. And set it again if it is shown again
MasterController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = "Master Title"
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationItem.title = ""
}
And this is how I push a UIViewController and clear the back bar button item in the child controller:
MasterController
let childController = ChildController(collectionViewLayout: UICollectionViewFlowLayout())
childController.navigationItem.backBarButtonItem?.title = ""
navigationController?.pushViewController(childController, animated: true)
Following code can be added to a view controller from where you are pushing view controller in which you want to change back button text
Swift 5
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
For example:-
ViewController1
ViewController2
Assume we want to update back title of viewcontroller2 and we are pushing viewcontroller2 from viewcontroller1.
then you can use following code:-
let vc2 = storyboard.instantiateViewController(withIdentifier: "ViewController2")
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "your custom back button title", style: .plain, target: self, action: nil)
self.navigationController?.pushViewController(vc2, animated: true)
Set self.title = ""
before self.navigationController?.pushViewController(vc, animated: true).
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.navigationItem.title = "Notes"
let sendButton = UIBarButtonItem(title: "New", style: .plain, target: self, action: #selector(goToNoteEditorViewController))
self.tabBarController?.navigationItem.rightBarButtonItem = sendButton
}
func goToNoteEditorViewController(){
// action what you want
}
Hope it helps!! #swift 3
If you are pushing a view controller from page view controller page, you cannot update the navigation controller's back button title. To solve this create a delegate back to your parent view controller (you may also be able to traverse the view controller hierarchy back up to the parent).
Furthermore, Back buttons have a character limit. If you exceed that character limit, the system will default to "Back". It will not truncate for you. For example:
backItem.title = "Birthdays/Anniversaries" // Get's converted to "Back".
backItem.title = "Birthdays/Anniversa…" // Fits and shows as is.
for Swift 4.2
let backItem = UIBarButtonItem()
backItem.title = ""
navigationItem.backBarButtonItem = backItem
GOTCHA: If you are having trouble with any of the many-starred suggestions, ensure that you are registering your UITableViewCells in viewDidLoad(), not from init()
Solution checked and work in Swift 5
Below I put few solutions for different cases:
1. Remove text from back button
The best solution to remove text from back button is to add in viewDidLoad():
navigationItem.backBarButtonItem = UIBarButtonItem()
2. Set own text on back button
In case you want to set your own title, do it by setting title of backButton:
let backButton = UIBarButtonItem()
backButton.title = "My Title"
navigationItem.backBarButtonItem = backItem
3. Empty back button on all VC
If you want to create common style in entire app - to have just arrow back without text, create base VC for all your View Controllers:
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.backBarButtonItem = UIBarButtonItem()
}
}
Solution presented above let you customize back button in the future if you want to make some exception later, by adding additional variable and overriding it in specific ViewController, f.ex:
class BaseViewController: UIViewController {
var customBackButtonTitle: String?
override func viewDidLoad() {
super.viewDidLoad()
var backButton = UIBarButtonItem()
if let text = customBackButtonTitle {
backButton.title = text
}
navigationItem.backBarButtonItem = backButton
}
}
There has two of different ways to Implanting that part those are ,
1.
navigationItem.backButtonTitle = "Title Goes Here"
(swift 5)
2.
let backButton = UIBarButtonItem()
backButton.title = "Title Goes Here"
self.navigationController?.navigationBar.topItem?.backBarButtonItem = backButton