Customised navigation bar back button title - ios

I want customised navigation bar back button title with action.
My Image :
I need back button like this. Here i added text successfully, but not back arrow. Here my code has action for back button.
This is my code
//Custom barButtonItem with custom alert function
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "< Dialer", style: .plain, target: self, action: #selector(back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
When i add above code it's getting like this.

func backButtonConfiguration(_ title : String, backImageName : String) {
let backImage : UIImage = UIImage(named: backImageName)!
self.navigationBar.backIndicatorImage = backImage.withRenderingMode(.alwaysTemplate)
self.navigationBar.backIndicatorTransitionMaskImage = backImage
self.navigationBar.backItem?.title = title
}
Update
if we need custom action for back button then we have to add custom BarButtonItem. And if we need bar back button look same as built in back button then we can create custom view and use it it as a bar button item
weak var customView : UIView!
lazy var leftBarButtonView : UIBarButtonItem! = {
let btnBack = UIBarButtonItem(customView: customView)
let gesture = UITapGestureRecognizer(target: self, action: #selector(btnButtonClicked(_:)))
gesture.numberOfTapsRequired = 1
self.customView.addGestureRecognizer(gesture)
self.customView.isUserInteractionEnabled = true
return btnBack
}()
#objc func btnButtonClicked(_ gesture : UITapGestureRecognizer) {
self.navigationController?.popViewController(animated: true)
}
self.navigationItem.leftBarButtonItems = [leftBarButtonView]

Related

Why does setting a custom backBarButtonItem for a UINavigationItem result in double back buttons?

I have a very simple setup. A UINavigationController with a root UIViewController that modifies its navigation item with a custom back button item on viewDidLoad.
let backButton = UIBarButtonItem(image: backArrowImage,
style: .plain,
target: nil,
action: nil)
navigationItem.backBarButtonItem = backButton
I'm expecting this to completely replace the system back button with title and the default back arrow icon.
However when I push a new view controller on the stack, the navigation bar draws both the new custom back icon and the system back icon.
This is what I'm seeing:
This is what I would expect it to look like:
You can hide the back button
navigationItem.hidesBackButton = true
and use leftBarButtonItem for custom UIBarButtonItem
UPD
import UIKit
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesBackButton = true
let backItem = UIBarButtonItem(image: backArrowImage, style: .plain, target: self, action: #selector(backButtonPressed))
navigationItem.leftBarButtonItem = backItem
}
#objc func backButtonPressed() {
navigationController?.popViewController(animated: true)
}
}
let backBarButtonItem: UIBarButtonItem = .init(
image: UIImage(systemName: "chevron.backward"),
style: .plain,
target: target,
action: action
)
navigationBar.topItem?.backBarButtonItem = backBarButtonItem
navigationBar.backIndicatorImage = UIImage()
navigationBar.backIndicatorTransitionMaskImage = UIImage()
This works for me, to setup custom "<" and hide the default one and still keep the backBarButtonItem behaviours
The solution was to set global UINavigationBar appearance.
Apparently this has to be done at app launch.
UINavigationBar.appearance().backIndicatorImage = backArrowImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backArrowImage
With this approach we can preserve title animations and general back button behavior that would not be preserved if supplementing the back button with the leftBarButtonItem.

How to make a UIBarButtonItem perform a function when pressed?

I am trying to make a custom back button using this code:
let back = UIImage(named: "header_backarrow")
let backView = UIImageView(image: back)
let backItem = UIBarButtonItem(customView: backView)
navigationItem.leftBarButtonItem = backItem
I want the navigation item to perform this code:
func dismissManual() {
dismiss(animated: true, completion: nil)
}
I have tried many things like following this Stack Overflow post: Execute action when back bar button of UINavigationController is pressed
I have also tried making it a navigationItem.backBarButtonItem; however, nothing seems to work. Some things show the correct custom image, but do not work as a button; on the other hand, some work as a button, but do not show the correct image.
Does anybody know how I can show the correct image and make the item work as a button? Thanks.
Do it as follows:
override func viewDidLoad() {
super.viewDidLoad()
let back = UIImage(named: "header_backarrow")
let backView = UIImageView(image: back)
backView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissManual))
backView.addGestureRecognizer(tap)
let backItem = UIBarButtonItem(customView: backView)
navigationItem.leftBarButtonItem = backItem
}
#objc func dismissManual() {
print("print----")
// dismiss(animated: true, completion: nil)
}
Add gesture to backView it will work!
It's similiar to this question IOS - Swift - adding target and action to BarButtonItem's customView
Swift 4.1
The issue is that UIImage does not have tap recognition. You will have to add a tap gesture recognizer to your backView.
lazy var singleTap: UITapGestureRecognizer = {
let singleTap = UITapGestureRecognizer(target: self, action: #selector(tapDetected))
singleTap.numberOfTapsRequired = 1
return singleTap
}()
// Actions
#objc func tapDetected() {
dismiss(animated: true, completion: nil)
}
If you show your code, with some screenshots I can give more help if this doesn't solve the issue.
You are creating your UIBarButtonItem incorrectly. You do not need the image view.
Do it as follows:
let back = UIImage(named: "header_backarrow")
let backItem = UIBarButtonItem(image: back, style: .plain, target: self, action: #selector(dismissManual))
navigationItem.leftBarButtonItem = backItem
#objc func dismissManual() {
dismiss(animated: true, completion: nil)
}
Note that the function must be marked with #objc.
Depending on your image and how you want it displayed, you may need to create the image as follows:
let back = UIImage(named: "header_backarrow").withRenderingMode(.alwaysOriginal)
Another option is to create a UIButton with the image and setup to call your dismissManual function. Create the UIBarButtonItem with the button as the custom view.
But it's easier to create a standard UIBarButtonItem when all you have is a simple image or a simple string.
let barButtonItem = UIBarButtonItem(image: UIImage(named: "backImgs"),
style: .plain,
target: self,
action: #selector(menuButtonTapped))
// Adding button to navigation bar (rightBarButtonItem or leftBarButtonItem)
self.navigationItem.rightBarButtonItem = barButtonItem
// Private action
#objc fileprivate func menuButtonTapped() { // body method here }
Check out this, it may help Thanks.

How to change UINavigationController Title & backButton programming?

I have two viewControllers.
vc1 -> presentVC -> vc2
vc2 inherit UINavigationController
I want to set title & backButton in vc2,but it doesn't work.
class vc2: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// set title!!!
//self.navigationItem.title = "123"
//self.navigationController?.navigationBar.topItem?.title = "123"
//self.title = "123"
//self.navigationBar.topItem?.title = "123"
//self.navigationItem.title = "123"
// set backButton!!!
let navButtonWidth:CGFloat = 44
let backButton:UIButton = UIButton()
backButton.setImage(backImage, for: .normal)
backButton.addTarget(self, action: #selector(back), for: .touchUpInside)
self.navigationItem.leftBarButtonItems = [UIBarButtonItem(customView: backButton)]
}
Place the code below in perform(segue) or viewWillDissappear depended on how do you do your presentation - via Storyboard segue or manually from code.
let backButton = UIBarButtonItem()
backButton.title = "whatever_you_want"
navigationItem.backBarButtonItem = backButton
And in viewDidLoad of your vc2 simply put
navigationItem.title = "Controller title"
I can change it in storyboard Or change it in code.
I usually do this.
First hide navigation bar from default navigation controller.
navigationController?.navigationBar.hidden = true
Create navigation bar in storyboard and outlet it.
#IBOutlet weak var navigationBar: UINavigationBar!
Create custom navigation item.
private lazy var customNavigationItem: UINavigationItem = {
let navigationItem = UINavigationItem()
let backButton = UIBarButtonItem(image: UIImage(named: "cancel_icon"), style: .Plain, target: self, action: #selector(cancelTapped))
navigationItem.leftBarButtonItem = backButton
navigationItem.title = "Your Title"
return navigationItem
}()
Add custom navigation item to navigation bar
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.hidden = true
navigationBar.setItems([customNavigationItem], animated: false)
}
Hope it help.

Setting up the back button in navigation controller

I seem to be unable to correctly set up the back button of the navigationController programmatically that shows when a previous view uses
self.navigationController?.pushViewController(newView, animated: true)
I hide all of the views from the previous view in it's viewDidDisappear using a loop and in the new view presented in the viewDidAppear I attempt to set the action of the back button in various ways; however, while I can succeed in manipulating the back button that is automatically shown such as hiding it or changing it's image I am unable to set up it's action.
Any insight would be appreciated as none of the answers I have found seem to work correctly. Also this is done without any use of the storyboard
if let img = UIImage(named: "backButton") {
self.navigationController?.navigationBar.backIndicatorImage = img
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = img
print("IMAGE")
}
topItem.backBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Rewind, target: self,
action:#selector(self.backButtonAction(_:)))
In your case add a custom button on the Navigation.
class YourViewController: UIViewController {
//Navigation Items.
//left bar button item.
private var leftBarButtonItem : UIBarButtonItem!
//left button.
private var navigationLeftButton : UIButton!
//Your other variable/object declaration.
func viewDidLoad() {
super.viewDidLoad()
self.leftBarButtonItem = UIBarButtonItem()
}
func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.setNavigationBackButton()
}
private func setNavigationBackButton() {
if(self.navigationLeftButton == nil) {
self.navigationLeftButton = UIButton(type: UIButtonType.System)
}
//Styling your navigationLeftButton goes here...
self.navigationLeftButton.addTarget(self, action: Selector("backButtonTapped"), forControlEvents: UIControlEvents.TouchUpInside)
self.leftBarButtonItem.customView = self.navigationLeftButton
self.navigationItem.leftBarButtonItem = self.leftBarButtonItem
}
func backButtonTapped(AnyObject:sender) {
// Here add your custom functionalities.
// Note, this will not pop to previous viewcontroller,
}
}

performSegue with programmatically added Navigation button

I am trying to customize a Navigation bar button item programmatically... I am just having some issues here which I am sure is an easy fix. I want to make it the default Add button for now, but also in the future will want to make the bar button item a custom icon I create. so I guess I would like to know both ways how to programmatically change a navigation bar button to default styles and custom icons...thanks!
override func viewDidAppear(animated: Bool) {
let rightbutton = UIBarButtonItem(title: "+", style: UIBarButtonItemStyle.Plain, target: self, action: "uploadButtonClicked")
navigationItem.rightBarButtonItem = rightbutton
}
Here is how you would do it with the default add button:
let button = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: "uploadButtonClicked")
self.navigationItem.rightBarButtonItem = button
Here is how you would programmatically add a custom image:
let customImage = UIImage(named: "customButtonImage")
let customButton = UIBarButtonItem(image: customImage, style: UIBarButtonItemStyle.Plain, target: self, action: "uploadButtonClicked:")
self.navigationItem.rightBarButtonItem = customButton
To perform the segue, you can do this:
#IBAction func uploadButtonClicked(sender: UIBarButtonItem) {
performSegueWithIdentifier("segueIdentifier", sender: self)
}
Or, if you want to go to another storyboard from there, then your IBAction will look like this:
#IBAction func uploadButtonClicked(sender: UIBarButtonItem) {
let storyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let nc = storyboard.instantiateInitialViewController() as! UINavigationController
let vc = nc.viewControllers.first as! YourViewController

Resources