I am trying to set a custom image for the back bar button. I can remove the text, however, the default chevron arrow is still there. As illustrated below;
I'm on x-code 11.3
My code is;
let chevronImage = UIImage(systemName: "arrow.left")!.withAlignmentRectInsets(UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 0))
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
navigationController?.navigationBar.backIndicatorImage = chevronImage
navigationController?.navigationBar.backIndicatorTransitionMaskImage = chevronImage
You could try something like this:
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "arrow.left"),
style: .plain,
target: nil,
action: nil)
Try create your own custom navigation bar class and use that in viewDidLoad() function
let backButtonBackgroundImage = UIImage(named: "ic_navbar_back")!
let barAppearance = UINavigationBar.appearance(whenContainedInInstancesOf[CustomNavBar.self])
barAppearance.backIndicatorImage = backButtonBackgroundImage
barAppearance.backIndicatorTransitionMaskImage = backButtonBackgroundImage
Try this:
self.navigationController?.navigationBar.backIndicatorImage = images
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = images
self.navigationController?.navigationBar.tintColor = UIColor.clear
I have a navigationController which is being used to move between my ViewControllers.
I have it setup normally and I am using Xib's for each View Controller.
extension UINavigationController{
func setup(){
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationItem.largeTitleDisplayMode = .always
} else {
// Fallback on earlier versions
}
self.navigationBar.isTranslucent = true
self.view.backgroundColor = UIColor.red
self.navigationBar.clipsToBounds = true
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.tintColor = UIColor(hexString: "#373839")
}
}
This is the extension I am using for my UINavigation Controller.
And in the pushed View (Second View), I need to have different Left and right buttons so I am hiding the navigation backbitten and having a custom code to setup my buttons.
func setUI(){
self.navigationController?.navigationItem.hidesBackButton = true
self.navigationController?.navigationBar.clipsToBounds = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let hostStr = host
print(hostStr)
let searchImage = UIImage(named: "Search_Icon3")!
let notificationImage = UIImage(named: "Notification_Icon3")!
let profileImage = UIImage(named: "test_Profile")!
let backImage = UIImage(named: "Back_Icon3")!
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(searchViewButtonPressed(_:)))
let notificationButton = UIBarButtonItem(image: notificationImage, style: .plain, target: self, action: #selector(notificationViewButtonPressed(_:)))
let profileButton = UIBarButtonItem(image: profileImage, style: .plain, target: self, action: #selector(profileViewButtonPressed(_:)))
let backButton = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(backButtonPressed(_:)))
self.navigationItem.rightBarButtonItems = [profileButton,notificationButton,searchButton]
self.navigationController?.navigationBar.tintColor = UIColor(hexString: "#373839")
self.navigationItem.leftBarButtonItem = backButton
self.setValues()
}
But when I push from ViewController 1 to 2 and Pop from 2 to 1 I get this weird Nav bar present effect between transition
I add a right navigation bar item that has a coloured background image:
let rightButton = UIBarButtonItem(image: UIImage(named: "avatar")!,
style: UIBarButtonItemStyle.Plain,
target: self,
action: #selector(self.rightNavBarItemAction))
navigationItem.rightBarButtonItem = rightButton
Instead of having the image as the background of the button (in colours), I get a white placeholder.
You can update the image's rendering mode to
UIImageRenderingMode.alwaysOriginal.
Swift 4.2:
let img = UIImage(named: "avatar")!.withRenderingMode(.alwaysOriginal)
let rightButton = UIBarButtonItem(image: img,
style: UIBarButtonItem.Style.Plain,
target: self,
action: #selector(self.rightNavBarItemAction))
Swift 4:
let img = UIImage(named: "avatar")!.withRenderingMode(.alwaysOriginal)
let rightButton = UIBarButtonItem(image: img,
style: UIBarButtonItemStyle.Plain,
target: self,
action: #selector(self.rightNavBarItemAction))
Swift 3:
let img = UIImage(named: "avatar")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
let rightButton = UIBarButtonItem(image: img,
style: UIBarButtonItemStyle.Plain,
target: self,
action: #selector(self.rightNavBarItemAction))
Alternatively you can set a custom view as in Vladimir's answer.
To achieve this you need a button UIButton, set the image of that button and then assigned it as the custom view if your UIBarButtonItem:
let button = UIButton()
button.frame = CGRectMake(0, 0, 51, 31)
button.setImage(UIImage(named: "avatar"), forState: .Normal)
button.addTarget(self, action: #selector(self.rightNavBarItemAction)), forControlEvents: .TouchUpInside)
let barButton = UIBarButtonItem()
barButton.customView = button
self.navigationItem.rightBarButtonItem = barButton
I'm trying to put a rightBarButtonItem on a second view controller of an UINavigationViewController stack.
I'm creating and setting the button in viewDidLoad of the view controller that I want to show. My actual code looks like this:
override func viewDidLoad() {
super.viewDidLoad()
menu_button_ = UIBarButtonItem(image: UIImage(named: "menu"),
style: UIBarButtonItemStyle.Plain ,
target: self, action: "OnMenuClicked:")
self.navigationController!.navigationItem.rightBarButtonItem = menu_button_
}
What am I missing? The button doesn't appear.
You should set the menu_button_ as the rightBarButtonItem of your viewController rather than the navigationController.
Try
self.navigationItem.rightBarButtonItem = menu_button_
instead of
self.navigationController!.navigationItem.rightBarButtonItem = menu_button_
try with following code. it works for me.
let homeButton : UIBarButtonItem = UIBarButtonItem(title: "LeftButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: "")
let logButton : UIBarButtonItem = UIBarButtonItem(title: "RigthButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: "")
self.navigationItem.leftBarButtonItem = homeButton
self.navigationItem.rightBarButtonItem = logButton
And if you want to settle out custom image then please check with apple guidelines on below link.
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/BarIcons.html#//apple_ref/doc/uid/TP40006556-CH21-SW1
In Swift 5
//For righter button item
let rightBtn = UIBarButtonItem(image: UIImage(named: "rightmenu"), style: .plain, target: self, action: #selector(onClickMethod))//Change your function name and image name here
self.navigationItem.rightBarButtonItem = rightBtn
//self.navigationItem.rightBarButtonItem = [rightBtn, anotherBtn] //If you want to add more buttons add like this
//This is your function
#objc func onClickMethod() {
print("Left bar button item")
}
Create an extension of UINavigationItem like -
extension UINavigationItem {
func addSettingButtonOnRight(){
let button = UIButton(type: .custom)
button.setTitle("setting", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 15.0)
button.layer.cornerRadius = 5
button.backgroundColor = .gray
button.frame = CGRect(x: 0, y: 0, width: 100, height: 25)
button.addTarget(self, action: #selector(gotSettingPage), for: UIControlEvents.touchUpInside)
let barButton = UIBarButtonItem(customView: button)
self.rightBarButtonItem = barButton
}
#objc func gotSettingPage(){
}
}
And call it from viewDidLoad() like -
self.navigationItem.addSettingButtonOnRight()
I would like to have more than a single UIBarButtonItem on the right side of my UINavigationBar. How can I achieve this?
An example of what I am trying are shown below - you can notice that the top right has more than one button.
Use this in swift:
override func viewDidLoad() {
super.viewDidLoad()
let editImage = UIImage(named: "plus")!
let searchImage = UIImage(named: "search")!
let editButton = UIBarButtonItem(image: editImage, style: .Plain, target: self, action: "didTapEditButton:")
let searchButton = UIBarButtonItem(image: searchImage, style: .Plain, target: self, action: "didTapSearchButton:")
navigationItem.rightBarButtonItems = [editButton, searchButton]
}
Write the action functions like this:
func didTapEditButton(sender: AnyObject){
...
}
func didTapSearchButton(sender: AnyObject){
...
}
Swift 4 & 5
override func viewDidLoad() {
super.viewDidLoad()
let editImage = UIImage(named: "edit")!
let searchImage = UIImage(named: "search")!
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(didTapEditButton(sender:)))
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(didTapSearchButton(sender:)))
navigationItem.rightBarButtonItems = [editButton, searchButton]
}
#objc func didTapEditButton(sender: AnyObject){
}
#objc func didTapSearchButton(sender: AnyObject){
}
-(void)viewDidLoad{
UIBarButtonItem *anotherButton1 = [[UIBarButtonItem alloc] initWithTitle:#"Button_1" style:UIBarButtonItemStylePlain target:self action:#selector(button_1:)];
UIBarButtonItem *anotherButton2 = [[UIBarButtonItem alloc] initWithTitle:#"Button_" style:UIBarButtonItemStylePlain target:self action:#selector(button_2:)];
self.navigationItem.rightBarButtonItems=#[anotherButton1,anotherButton2];
}
In Swift 3 you can use:
let editImage = UIImage(named: "plus")!
let searchImage = UIImage(named: "search")!
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(didTapEditButton))
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(didTapSearchButton))
navigationItem.rightBarButtonItems = [editButton, searchButton]
I think nothing of the above is going to work
Try this
var burgerItem = UIBarButtonItem(image: UIImage(named:"categories"), style: .Plain, target: self, action: "categories")
var weatherItem = UIBarButtonItem(title: "Weather", style: .Plain, target: self, action: "weather")
burgerItem.tintColor = UIColor.whiteColor()
weatherItem.tintColor = UIColor.whiteColor()
navigationItem.setRightBarButtonItems([burgerItem,weatherItem], animated: true)
You have to use navigationItem.setRightBarButtonItems and be carefull. navigationItem has to be of a view controller.
class testViewController:UIViewController {
ovverride func viewDidLoad() {
self.navigationItem.setRightBarButtonItems(...
}
}
Simply add this code:
self.navigationItem.leftBarButtonItem = nil
let button = UIButton(type: .custom)
button.setImage(UIImage (named: "ChatTab"), for: .normal)
button.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)
let button2 = UIButton(type: .custom)
button2.setImage(UIImage (named: "ActivityTab"), for: .normal)
button2.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)
let barButtonItem2 = UIBarButtonItem(customView: button2)
self.navigationItem.rightBarButtonItems = [barButtonItem, barButtonItem2]
This is the result:
With Swift 4
let editImage = UIImage(named: "toolbar_edit")!
let favoriteImage = UIImage(named: "toolbar_fav_solid")!
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(didTapEditButton))
let favoriteButton = UIBarButtonItem(image: favoriteImage, style: .plain, target: self, action: #selector(didTapFavoriteButton))
navigationItem.rightBarButtonItems = [editButton, favoriteButton]
Click action for those buttons
#objc func didTapEditButton(sender: AnyObject) {
print("edit")
}
#objc func didTapFavoriteButton(sender: AnyObject) {
print("favorite")
}
Output screenshot (iPhone X)
Accepted answer as well as few of the answer is absolutely correct but in my case none of them work.
Reason : My View Controller was Inherited from UIViewController and I had to set Add to Cart Button and Search Button On Right hand side. And All my view controllers were a part of UITabbarController.
let editImage = UIImage(named: "OrdersTabIcon")
let searchImage = UIImage(named: "OrdersTabIcon")
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(iconTapped))
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(iconTapped))
Instead of using
self.navigationItem.setRightBarButtonItems([editButton, searchButton], animated: true)
Use This .
self.navigationController?.navigationBar.topItem?.setRightBarButtonItems([editButton, searchButton], animated: true)
This is may be help for you in objective-c,
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.navigationItem.title = #"Title";
UIBarButtonItem *logOutButton = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStylePlain target:self action:#selector(ButtonClickedAtIndex1:)];
[logOutButton setTintColor:[UIColor blackColor]];
logOutButton.tag = 1;
UIBarButtonItem *syncBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Sync" style:UIBarButtonItemStylePlain target:self action:#selector(ButtonClickedAtIndex1:)];
[syncBarButtonItem setTintColor:[UIColor blackColor]];
syncBarButtonItem.tag = 2;
self.navigationItem.leftBarButtonItem = logOutButton;
self.navigationItem.rightBarButtonItem = syncBarButtonItem;
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
self.navigationController.navigationBar.translucent = NO;
}
}
return self;
}
Use navigationItem's rightBarButtonItems, which takes an array of UIBarButton. Appledoc
let share = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareTapped))
let add = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTapped))
navigationItem.rightBarButtonItems = [add, share]
I don't know wether an Interface Builder solution was not possible before, but at least with the most recent update (Xcode 11.0), it is possible to drag two UI Bar Buttons into the rightBarButton space. Two outlets and actions can then be dragged into the code like always.
Since the OP didn't ask for a solution without IB, I think this also qualifies as an answer.
For Xamarin iOS with the new updates, it is like:
UIBarButtonItem Button1 = new UIBarButtonItem(UIImage.FromBundle("Image1"), UIBarButtonItemStyle.Plain,YourEventHandler);
UIBarButtonItem Button2 = new UIBarButtonItem(UIImage.FromBundle("Image1"), UIBarButtonItemStyle.Plain,YourEventHandler);
NavigationItem.SetRightBarButtonItems(new[]{ Button1, Button2 }, true);