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
Related
In my app I have a push segue from HomeViewController to EditProfileViewController which should have a back button as a leftBarItem and a settings cog as a rightBarItem. The back button displays normally, but the right item is missing. These ViewControllers live happen in the MainNavigationController which has a Navigation Bar.
I tried to define the rightBarButton in ViewDidLoad of the EditProfileVC, I also tried to have a rightBarItem in the storyboard for the View controller.
let buttonItem = UIBarButtonItem(image: settingsIcon, style: .plain, target: self, action: #selector(settingsPressed))
buttonItem.tintColor = UIColor(.settingsIconTint)
navigationItem.rightBarButtonItem = buttonItem
Interestingly if I change the rightBar to a leftBar item, the back button is replaced with the settings cog and works as I expect, but I can't go back to the main page.
let buttonItem = UIBarButtonItem(image: settingsIcon, style: .plain, target: self, action: #selector(settingsPressed))
buttonItem.tintColor = UIColor(.settingsIconTint)
navigationItem.leftBarButtonItem = buttonItem
To set a rightBarButtonItem in a navigationBar,
class HomeViewController: UIViewController {
#IBAction func openEditVC(_ sender: UIButton) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "EditProfileViewController") as? EditProfileViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
}
}
class EditProfileViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let buttonItem = UIBarButtonItem(title: "Settings", style: .plain, target: self, action: #selector(settingsPressed))
buttonItem.tintColor = .red
navigationItem.rightBarButtonItem = buttonItem
}
#objc func settingsPressed() {
print("Setting Pressed")
}
}
In the above code I've added a UIBarButtonItem with title Settings as a rightBarButtonItem of navigationBar.
No need to configure leftBarButtonItem it not required. Back button is added by default.
Screenshot:
In case it doesn't satisfy your requirement, add a screenshot of what is expected so I can help.
let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: Selector(("HomeTabController")))
self.navigationItem.leftBarButtonItem = backButton
The above code is the creation of button in navigationController but I can create a button cannot write a specific view controller to open.
I have tried with popViewController and popToRootViewController action, need a specific code for opening a particular viewController in swift, with the help of the particular viewController storyboard id and viewcontrollername.
You need to add func name in #selctor() (Swift 4 version)
let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(goToViewController(_:)))
self.navigationItem.leftBarButtonItem = backButton
You need to create a func.
#objc func goToViewController(_ sender: UIBarButtonItem) {
//write code here to open a view controller
let storyboard = "Main"
let viewControllerIdentifier = "HomeVC"
let viewController = UIStoryboard(name: storyboard, bundle: nil).instantiateViewController(withIdentifier: viewControllerIdentifier) as! HomeVC
//push/present "viewController"
}
in this code just replace ChatVC name to your viewcontroller name
#objc func goToViewController(_ sender: UIBarButtonItem) {
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: ChatVC.self) {
self.navigationController!.popToViewController(controller, animated: true)
break
} else {
self.navigationController?.popViewController(animated: true)
}
}
}
I'm relatively new at iOS. I'm struggling, for a while now with this issue. I don't know how to set the logic for presenting popUp when user taps on right bar button item. Basically, it should look like this:PopUp I searched through Google, but I didn't have any luck. I would appreciate if someone would help me with some code.
//My VC
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let rightBarButtonItem = UIBarButtonItem(title: "Share", style: .plain, target: self, action: #selector(clickShare))
rightBarButtonItem.tintColor = UIColor.black
navigationItem.rightBarButtonItem = rightBarButtonItem
// navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Share", style: UIBarButtonItemStyle.plain, target: self, action: #selector(clickShare))
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "backArrow"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(goBack))
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font : UIFont(name: "OpenSans", size: 14)! ], for: .normal)
}
//MARK: - Actions
#objc func goBack() {
navigationController?.popViewController(animated: true)
}
#objc func clickShare() {
//this is where the logic should go
}
//This is my storyboard:
Storyboard
Add following action,
#IBAction func yourButtonClickAction(sender: UIBarButtonItem) {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("YourViewController") as! UIViewController
vc.modalPresentationStyle = UIModalPresentationStyle.Popover
let popover: UIPopoverPresentationController = vc.popoverPresentationController!
popover.barButtonItem = sender
popover.delegate = self
presentViewController(vc, animated: true, completion:nil)
}
Add this action to you barButtonItem.
'YourViewController' = controller consisting of Public, followers options.
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.
I have added a navigation bar to the top of a view controller. I am trying to control whether a button is visible based a condition, but I am having trouble adding the button. So far I have,
var addButton: UIBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(addTapped))
override func viewDidLoad() {
super.viewDidLoad()
let boool = true
if boool {
self.navigationItem.rightBarButtonItem = self.addButton
}
else {
self.navigationItem.rightBarButtonItem = nil
}
}
func addTapped(sender: AnyObject) {
print("hjxdbsdhjbv")
}
I believe it is not working properly because I have added a navigation bar into the VC, instead of using a navigation controller and working with the bar there. I was wondering if there was a way to work with this navigation bar.
It’s simple. Put this line of code to the viewDidLoad:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(addTapped))
Updated for Swift 4 or later:
A custom function:
#objc func action(sender: UIBarButtonItem) {
// Function body goes here
}
(Custom) Right bar button item:
self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "some_text", style: .done, target: self, action: #selector(self.action(sender:)))
(Custom) Left bar button item:
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(title: "some_text", style: .done, target: self, action: #selector(self.action(sender:)))
Also you can add a system bar button items something like this: UIBarButtonItem.SystemItem Defines system-supplied images for bar button items: .add, .done, .cancel, .edit, .save, .compose, .reply, .organize and more.
(System) Right bar button item:
self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.action(sender:)))
(System) Left bar button item:
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.action(sender:)))
let rightBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "EditImage"), style: .done, target: self, action: #selector(ViewController.call_Method))
self.navigationItem.rightBarButtonItem = rightBarButtonItem
You say you added a UINavigationBar to your view controller via storyboard, but looking at the code you provided there is no outlet connection to your navigation bar in IB.
In order to access self.navigationItem your view controller must be embedded in a UINavigationController or be part of a hierarchy which is. Unless you have a need for a custom navigation bar on an individual view controller, I suggest removing that from Interface Builder, then making sure either the view controller in question is embedded in a UINavigationController or it is being pushed onto the navigation stack from another controller which is embedded in a navigation controller and then you should see your UIBarButtonItem.
Firstly, you need to connect you navigation bar to an IBOutlet so that you can refer to it in your code. After that, this code should work:
let navigationItem = UINavigationItem(title: "Title")
navigationItem.rightBarButtonItem = self.addButton
navigationItem.hidesBackButton = true
self.navigationBar.pushItem(navigationItem, animated: false)
Swift 4.2;
Add viewController
override func viewDidLoad() {
super.viewDidLoad()
self.addNavigationBarButton(imageName: "ic_back", direction:.left)
}
Add Class your API or Utility Class
public func addNavigationBarButton(imageName:String,direction:direction){
var image = UIImage(named: imageName)
image = image?.withRenderingMode(.alwaysOriginal)
switch direction {
case .left:
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
case .right:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
}
}
#objc public func goBack() {
self.navigationController?.popViewController(animated: true)
}
public enum direction {
case right
case left
}
tested in Xcode 10.2, swift 5.0;
First, I have have embedded my ViewController in UINavigationController in IB.
Then in ViewDidLoad include these lines
self.title = "orange"
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(changeLayout)).
Note - accessing title, or adding button through navigation controller did not work. For example : setting title - Self.navigationcontroller.navigationItem.title did not work ,