Unable to change backBarButtonItem in Swift - ios

I want to make my backBarButtonItem to be only < , without back. I have searched stackOverflow and found some solutions, but it stays < back.
I tried this in my pushed VC:
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
and also this, in my AppDelegate:
navigationController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
But none of two helped me. Anyone knows why?
This is how I push my ViewControllers:
let VC = XYZViewController()
self.navigationController?.pushViewController(VC, animated: true)

navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Write this piece of code in the controller from which you are pushing to the next controller

Related

How can I remove the text from the navigation bar back item

I'm trying to remove the text "Back" from the navigation back button, leaving just the back chevron, but everything I'm trying is not working. For example if I add something like the following, obtained from previous answers to the same question, to viewDidLoad:
navigationItem.backBarButtonItem = UIBarButtonItem(title: "go away", style: .plain, target: nil, action: nil)
or
navigationController?.navigationBar.backBarButtonItem = UIBarButtonItem(title: "go away", style: .plain, target: nil, action: nil)
Then when the view appears it's still showing "< Back" in the navigation bar.
Here's what the views look like within captured within viewDidAppear.
Image:1
Try this code snippet hope it will help you
happy coding =)
override func viewDidLoad() {
DispatchQueue.main.async {
if let navBar = self.navigationController?.navigationBar {
navBar.backItem?.title = ""
}
}
}
You should create a left button and set the action to return to the rootViewController.
In viewDidLoad:
let leftButton = UIBarButtonItem(title: "<", style: .plain, target: self, action: #selector(back(_ :)))
self.navigationItem.leftBarButtonItem = leftButton
You are changing the wrong thing. You use this code here to change the title for the back button.
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .done, target: self, action: #selector(handleBack))
By doing this you need to add a selector for the button as well. Cause if you click the back button nothing will happen. This is how you would do that.
#objc private func handleBack() {
navigationController?.popViewController(animated: true)
}
Hope this helps.
Alternatively, from Interface Builder, you can set previous UIViewController's Back Button on Navigation Item to " " (not empty string, space):

Pass a selector into an an extension

I am trying to tidy up a ViewController and would like to move the setup of a navigation item to an extension.
This is the code I am looking to move out of the ViewController:
private func setupNavigationItem() {
navigationItem.leftBarButtonItem = UIBarButtonItem.stashWhite(barButtonSystemItem: .cancel, target: self, selector: #selector(cancelBarButtonHandler))
navigationItem.rightBarButtonItem = UIBarButtonItem.stashRed(barButtonSystemItem: .save, target: self, selector: #selector(saveBarButtonItemHandler))
navigationItem.rightBarButtonItem?.isEnabled = false
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
I have then created this extension.
extension UINavigationItem {
func addSavingSetup(_ cancelBarButtonHandler: Selector, _ saveBarButtonItemHandler: Selector) {
leftBarButtonItem = UIBarButtonItem.stashWhite(barButtonSystemItem: .cancel, target: self, selector: cancelBarButtonHandler)
rightBarButtonItem = UIBarButtonItem.stashRed(barButtonSystemItem: .save, target: self, selector: saveBarButtonItemHandler)
rightBarButtonItem?.isEnabled = false
backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}
I then call it like so:
navigationItem.addSavingSetup(#selector(cancelBarButtonHandler(_:)), #selector(saveBarButtonItemHandler))
However I then get this error when tapping either the cancel or save bar button:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationItem cancelBarButtonHandler:]: unrecognized selector sent to instance 0x105e01e80
Any idea how I can solve this? Not sure how else to pass in the selector.
Thanks
You are setting different target. you need to pass target, like below
extension UINavigationItem {
func addSavingSetup(target: Any,_ cancelBarButtonHandler: Selector, _ saveBarButtonItemHandler: Selector) {
leftBarButtonItem = UIBarButtonItem.stashWhite(barButtonSystemItem: .cancel, target: target, selector: cancelBarButtonHandler)
rightBarButtonItem = UIBarButtonItem.stashRed(barButtonSystemItem: .save, target: target, selector: saveBarButtonItemHandler)
rightBarButtonItem?.isEnabled = false
backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}

Why setting the barItems is not working?

I have a UIViewController, and I embed it into a UINavigationController.
I want to show one item in the toolbar (and by toolbar, I mean this:
This is my code in viewDidLoad method
self.navigationController?.toolbarHidden = false
self.navigationController?.toolbar.items?.append(UIBarButtonItem(title: "Buy Potato", style: .Plain, target: self, action: #selector(ViewController.buyPotato)))
self.navigationController?.toolbarItems?.append(UIBarButtonItem(title: "Buy Potato", style: .Plain, target: self, action: #selector(ViewController.buyPotato)))
self.toolbarItems?.append(UIBarButtonItem(title: "Buy Potato", style: .Plain, target: self, action: #selector(ViewController.buyPotato)))
and I already have the method buyPotato
func buyPotato() {
}
as you see, I tried to do that using either the viewController or the navigationController, but it doesn't work.
All I can see is the toolbar at the bottom of my screen but without any button.
self.navigationController?.toolbarHidden = false
var items = [UIBarButtonItem]()
items.append(
UIBarButtonItem(barButtonSystemItem: .Plain, target: self, action: nil))
items.append(
UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "onClickedToolbeltButton:"))
self.setToolbarItems(barButtonItems, animated: true)
This has to work for you as per the answer written here.
Delete
self.setToolbarItems(barButtonItems, animated: true)
Add
self.toolbarItems = barButtonItems

UIBarbuttonItem action not working at all

I have a following helper class
class PDFPreviewHelper {
var pdfNavigationController: UINavigationController!
func previewButtonPressed(rootViewController: UIViewController) {
let pdfViewController = PDFViewController(resource: "final.pdf")
pdfNavigationController = UINavigationController(rootViewController: pdfViewController)
let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "backButtonPressedInPDF")
pdfViewController.navigationItem.setLeftBarButtonItem(backButton, animated: false)
rootViewController.presentViewController(pdfNavigationController, animated: true, completion: nil)
}
func backButtonPressedInPDF() {
pdfNavigationController.dismissViewControllerAnimated(true, completion: nil)
}
}
I call a function in above helper class in my rootviewcontroller like following:
func previewInPdfButtonPressed() {
let a = PDFPreviewHelper()
a.viewI129InPDF(self)
}
I successfully modally present pdfNavigationController on top of my rootViewController, but whenever i press back button, nothing gets called. Why is this so? I set a break point in backButtonPressedInPDF function and it doesn't even hit the break point.
You need to assign leftBarButtonItem to UINavigationController via below way.
pdfViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "backButtonPressedInPDF")
I think the problem lies here.
let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "backButtonPressedInPDF")
To:
let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "backButtonPressedInPDF:")
I believe the problem as at action: "backButtonPressedInPDF" where there is a missing :
In addition, change your method by adding (sender:AnyObject) also?
func backButtonPressedInPDF(sender:AnyObject) {
pdfNavigationController.dismissViewControllerAnimated(true, completion: nil)
}
The issue is you are creating a temporary instance of PDFPreviewHelper class and using it to present the view controller. Not keeping the reference.
This can be fixed in two ways:
Method 1: Add previewInPdfButtonPressed method to your PDFViewController class. Then change implementation like following.
let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: pdfViewController, action: "backButtonPressedInPDF")
Method 2:
You should keep the object a until you dismiss your PDFViewController-navigationcontroller.
Even if you do like this you will get an exception like
2016-03-16 15:43:03.140 XXXX[3757:585277] *** NSForwarding: warning: object 0x7ff5eb72be70 of class 'XXXX.PDFPreviewHelper' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[XXXX.PDFPreviewHelper backButtonPressedInPDF]
This is because you are not subclassing NSObject for your PDFPreviewHelper.
You can fix it in two ways,
Make PDFPreviewHelper as NSObject subclass.
Add dynamic
keyword to the function like dynamic func previewInPdfButtonPressed() {....}.
Resolution to this issue is well described here
func previewInPdfButtonPressed()
{
let a = PDFPreviewHelper()
a.viewI129InPDF(self)
}
The problem is a is released when the program goes out of the scope of this function. The action you target on a of course can't be executed anymore
solution add a as a property of the viewController

How to set backButton text to empty?

I tried this code:
navigationController?.navigationItem.backBarButtonItem?.title = ""
but it does not work and did not change anything. How can I set backButton text to empty?
I tried this code for back button title. and it's work correctly
let barButton = UIBarButtonItem()
barButton.title = ""
self.navigationController?.navigationBar.topItem?.backBarButtonItem = barButton
self.navigationController!.navigationBar.topItem!.title = ""
You should use:
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
for see just < instead of < viewController
You have to change the previous controller's title, try doing so before the segue in the viewDidDisappear
To remove the backButtonItem's title, place this line of code in the viewDidLoad: of the View Controller that the backButtonItem is in:
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain,
target: nil, action: nil)
self.navigationItem.leftBarButtonItem=nil;
or
self.navigationItem.backBarButtonItem=nil;

Resources