Related
I am trying to set an Image for bar button Item for that I have an image like:
with resolution 30 * 30 but while I assign this Image to Bar button Its looks like:
I have assigned image this way :
and If I try this way like making an IBOutlet for the button and set Image programatically form this question and code for that is:
// Outlet for bar button
#IBOutlet weak var fbButton: UIBarButtonItem!
// Set Image for bar button
var backImg: UIImage = UIImage(named: "fb.png")!
fbButton.setBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)
but nothing happend with this,
Can anybody tell me what I am doing wrong?
or which is the batter way to do this?
I have achieved that programatically with this code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
//set image for button
button.setImage(UIImage(named: "fb.png"), forState: UIControlState.Normal)
//add function for button
button.addTarget(self, action: "fbButtonPressed", forControlEvents: UIControlEvents.TouchUpInside)
//set frame
button.frame = CGRectMake(0, 0, 53, 31)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
func fbButtonPressed() {
println("Share to fb")
}
}
And result will be:
Same way you can set button for left side too this way:
self.navigationItem.leftBarButtonItem = barButton
And result will be:
And if you want same transaction as navigation controller have when you go back with default back button then you can achieve that with custom back button with this code:
func backButtonPressed(sender:UIButton) {
navigationController?.popViewControllerAnimated(true)
}
For swift 3.0:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button = UIButton.init(type: .custom)
//set image for button
button.setImage(UIImage(named: "fb.png"), for: UIControlState.normal)
//add function for button
button.addTarget(self, action: #selector(ViewController.fbButtonPressed), for: UIControlEvents.touchUpInside)
//set frame
button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
func fbButtonPressed() {
print("Share to fb")
}
}
For swift 4.0:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button = UIButton(type: .custom)
//set image for button
button.setImage(UIImage(named: "fb.png"), for: .normal)
//add function for button
button.addTarget(self, action: #selector(fbButtonPressed), for: .touchUpInside)
//set frame
button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
#objc func fbButtonPressed() {
print("Share to fb")
}
}
An easy solution may be the following
barButtonItem.image = UIImage(named: "image")
then go to your Assets.xcassets select the image and go to the Attribute Inspector and select "Original Image" in Reder as option.
Similar to the accepted solution, but you can replace the
let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
with
let button = UIButton()
Here is the full solution, enjoy: (it's just a bit cleaner than the accepted solution)
let button = UIButton()
button.frame = CGRectMake(0, 0, 51, 31) //won't work if you don't set frame
button.setImage(UIImage(named: "fb"), forState: .Normal)
button.addTarget(self, action: Selector("fbButtonPressed"), forControlEvents: .TouchUpInside)
let barButton = UIBarButtonItem()
barButton.customView = button
self.navigationItem.rightBarButtonItem = barButton
Here's a simple extension on UIBarButtonItem:
extension UIBarButtonItem {
class func itemWith(colorfulImage: UIImage?, target: AnyObject, action: Selector) -> UIBarButtonItem {
let button = UIButton(type: .custom)
button.setImage(colorfulImage, for: .normal)
button.frame = CGRect(x: 0.0, y: 0.0, width: 44.0, height: 44.0)
button.addTarget(target, action: action, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)
return barButtonItem
}
}
Only two Lines of code required for this
Swift 3.0
let closeButtonImage = UIImage(named: "ic_close_white")
navigationItem.rightBarButtonItem = UIBarButtonItem(image: closeButtonImage, style: .plain, target: self, action: #selector(ResetPasswordViewController.barButtonDidTap(_:)))
func barButtonDidTap(_ sender: UIBarButtonItem)
{
}
I am using latest swift (2.1) and the answer (Dharmesh Kheni and jungledev) does not work for me. The image color was off (when setting in IB, it was blue and when setting directly in UIButton, it was black). It turns out I could create the same bar item with the following code:
let barButton = UIBarButtonItem(image: UIImage(named: "menu"), landscapeImagePhone: nil, style: .Done, target: self, action: #selector(revealBackClicked))
self.navigationItem.leftBarButtonItem = barButton
You can use this code for multiple bar button with custom image:
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]
Result will be this:
Initialize barbuttonItem like following:
let pauseButton = UIBarButtonItem(image: UIImage(named: "big"),
style: .plain,
target: self,
action: #selector(PlaybackViewController.pause))
Your problem is because of the way the icon has been made - it doesn't conform to Apple's custom tab bar icon specs:
To design a custom bar icon, follow these guidelines:
Use pure white with appropriate alpha transparency.
Don’t include a drop shadow.
Use antialiasing.
(From the guidelines.)
Something that would be possible looks like this. You can find such icons on most free tab bar icon sites.
Swift 4.
#IBOutlet weak var settingBarBtn: UIBarButtonItem! {
didSet {
let imageSetting = UIImageView(image: UIImage(named: "settings"))
imageSetting.image = imageSetting.image!.withRenderingMode(.alwaysOriginal)
imageSetting.tintColor = UIColor.clear
settingBarBtn.image = imageSetting.image
}
}
SwiftUI
.navigationBarItems modifier takes any view you want:
struct ContentView: View {
var body: some View {
NavigationView {
Text("SwiftUI")
.navigationBarItems(leading:
HStack {
Image(systemName: "trash")
Text("Trash")
}
)
}
}
}
.navigationBarItems(trailing: Image(systemName: "trash") )
.navigationBarItems(leading: Image(systemName: "trash.fill"),
trailing: Image(systemName: "trash")
)
You can use a button for each if you need an action for each of them.
Swift 5+. Smooth solution to add ideal image as you desired dynamic Solution
func rightBarButtonItem(iconNameButton: String, selector: Selector) {
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
button.setImage(UIImage(named: iconNameButton), for: .normal)
button.addTarget(self, action: selector, for: .touchUpInside)
button.imageView?.contentMode = .scaleAspectFit
let buttonBarButton = UIBarButtonItem(customView: UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25)))
buttonBarButton.customView?.addSubview(button)
buttonBarButton.customView?.frame = button.frame
self.navigationItem.rightBarButtonItem = buttonBarButton
}
Just choose Original image option when adding an image to assets in Xcode
If your UIBarButtonItem is already allocated like in a storyboard.
(printBtn)
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
btn.setImage(UIImage(named: Constants.ImageName.print)?.withRenderingMode(.alwaysTemplate), for: .normal)
btn.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handlePrintPress(tapGesture:))))
printBtn.customView = btn
If you have set up your UIBarButtonItem with an image in the storyboard, one small hack to change the renderingMode is to add the following code to your viewDidLoad(). This way you don't have to resort to adding the entire button and image in code.
if let navButton = self.navigationItem.leftBarButtonItem, let buttonImage = navButton.image {
navButton.image = buttonImage.withRenderingMode(.alwaysOriginal)
}
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Left",
style: .plain,target: self, action: #selector(rightbarButtonAction))
navigationItem.rightBarButtonItem?.image = UIImage(named: "Notification Bell")
I want to change behavior of back button and I replace back button of Material with new bar button like bellow:
let backButton: UIButton = {
let btn = UIButton()
btn.setImage(UIImage(named: "prev"), for: .normal)
btn.frame = CGRect(x: 0, y: 0, width: 33/2, height: 27/2)
return btn
}()
In viewDidLoad function:
override func viewDidLoad() {
super.viewDidLoad()
backButton.action = { [weak self] in self?.showAlert() }
let barButton = UIBarButtonItem(customView: backButton)
navigationItem.backButton.isHidden = true
navigationItem.leftBarButtonItems = [barButton]
}
But I can not click to new back button because it was coverred by UINavigationBarBackIndicatorView.
How can I replace back button with Material. I want to keep Material library because in other features of project I need Material.
Thanks in advance for help.
Do this in your viewDidLoad() method :
self.navigationItem.backBarButtonItem.hidden = YES
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(YourViewController.back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
self.navigationItem.leftBarButtonItem?.image = UIImage(named : "prev")
self.navigationItem.leftBarButtonItem?.accessibilityFrame = CGRect(x: 0, y: 0, width: 33/2, height: 27/2)
Then define a function named back in your view controller,this function will perform the desired action for your new back button
func back(sender: UIBarButtonItem) {
// Perform your custom action
}
Note No need to define a separate button variable
**If self.navigationItem.backBarButtonItem.hidden = YES doesnt works then replace it with self.navigationItem.backBarButtonItem = nil; **
Using backButton.isHidden with leftViews containing the new custom IconButtom works for me, I'm using Material 2.17.0.
func setNavigation() {
let backButton = IconButton(image: Icon.cm.arrowBack)
backButton.addTarget(self, action: #selector(onBackTapped), for: .touchUpInside)
navigationItem.leftViews = [backButton]
navigationItem.backButton.isHidden = true
}
I am trying to left align back button i.e remove the space on the left of the back arrow . Using a custom back button .
let backButton = UIBarButtonItem(image: UIImage(named: "arrow03"), style: .Plain, target: self, action: "back")
self.navigationController?.navigationBar.tintColor = UIColor.clearColor()
self.navigationItem.backBarButtonItem = backButton
Tried to use negative width for the button as suggested in the below SO link but it didnt work.
How to Edit Empty Spaces of Left, Right UIBarButtonItem in UINavigationBar [iOS 7]
Image
http://imgur.com/PA9HLBm
Please help.
Refer below code to implement back button on left alignment.
let button: UIButton = UIButton (type: UIButtonType.Custom)
button.setImage(UIImage(named: "imageName"), forState: UIControlState.Normal)
button.addTarget(self, action: "backButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItem = barButton
Note - Make sure your image has to be plain ( transparent ) background.
func backButtonPressed(btn : UIButton) {
self.navigationController?.popViewControllerAnimated(true)
}
Swift 4 Code
override func viewDidLoad() {
super.viewDidLoad()
let button: UIButton = UIButton (type: UIButtonType.custom)
button.setImage(UIImage(named: "imageName"), for: UIControlState.normal)
button.addTarget(self, action: Selector(("backButtonPressed:")), for: UIControlEvents.touchUpInside)
button.frame = CGRect(x: 0 , y: 0, width: 30, height: 30)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItem = barButton
}
func backButtonPressed(btn : UIButton) {
self.navigationController?.popViewController(animated: true)
}
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 am trying to set an Image for bar button Item for that I have an image like:
with resolution 30 * 30 but while I assign this Image to Bar button Its looks like:
I have assigned image this way :
and If I try this way like making an IBOutlet for the button and set Image programatically form this question and code for that is:
// Outlet for bar button
#IBOutlet weak var fbButton: UIBarButtonItem!
// Set Image for bar button
var backImg: UIImage = UIImage(named: "fb.png")!
fbButton.setBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)
but nothing happend with this,
Can anybody tell me what I am doing wrong?
or which is the batter way to do this?
I have achieved that programatically with this code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
//set image for button
button.setImage(UIImage(named: "fb.png"), forState: UIControlState.Normal)
//add function for button
button.addTarget(self, action: "fbButtonPressed", forControlEvents: UIControlEvents.TouchUpInside)
//set frame
button.frame = CGRectMake(0, 0, 53, 31)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
func fbButtonPressed() {
println("Share to fb")
}
}
And result will be:
Same way you can set button for left side too this way:
self.navigationItem.leftBarButtonItem = barButton
And result will be:
And if you want same transaction as navigation controller have when you go back with default back button then you can achieve that with custom back button with this code:
func backButtonPressed(sender:UIButton) {
navigationController?.popViewControllerAnimated(true)
}
For swift 3.0:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button = UIButton.init(type: .custom)
//set image for button
button.setImage(UIImage(named: "fb.png"), for: UIControlState.normal)
//add function for button
button.addTarget(self, action: #selector(ViewController.fbButtonPressed), for: UIControlEvents.touchUpInside)
//set frame
button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
func fbButtonPressed() {
print("Share to fb")
}
}
For swift 4.0:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button = UIButton(type: .custom)
//set image for button
button.setImage(UIImage(named: "fb.png"), for: .normal)
//add function for button
button.addTarget(self, action: #selector(fbButtonPressed), for: .touchUpInside)
//set frame
button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
#objc func fbButtonPressed() {
print("Share to fb")
}
}
An easy solution may be the following
barButtonItem.image = UIImage(named: "image")
then go to your Assets.xcassets select the image and go to the Attribute Inspector and select "Original Image" in Reder as option.
Similar to the accepted solution, but you can replace the
let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
with
let button = UIButton()
Here is the full solution, enjoy: (it's just a bit cleaner than the accepted solution)
let button = UIButton()
button.frame = CGRectMake(0, 0, 51, 31) //won't work if you don't set frame
button.setImage(UIImage(named: "fb"), forState: .Normal)
button.addTarget(self, action: Selector("fbButtonPressed"), forControlEvents: .TouchUpInside)
let barButton = UIBarButtonItem()
barButton.customView = button
self.navigationItem.rightBarButtonItem = barButton
Here's a simple extension on UIBarButtonItem:
extension UIBarButtonItem {
class func itemWith(colorfulImage: UIImage?, target: AnyObject, action: Selector) -> UIBarButtonItem {
let button = UIButton(type: .custom)
button.setImage(colorfulImage, for: .normal)
button.frame = CGRect(x: 0.0, y: 0.0, width: 44.0, height: 44.0)
button.addTarget(target, action: action, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)
return barButtonItem
}
}
Only two Lines of code required for this
Swift 3.0
let closeButtonImage = UIImage(named: "ic_close_white")
navigationItem.rightBarButtonItem = UIBarButtonItem(image: closeButtonImage, style: .plain, target: self, action: #selector(ResetPasswordViewController.barButtonDidTap(_:)))
func barButtonDidTap(_ sender: UIBarButtonItem)
{
}
I am using latest swift (2.1) and the answer (Dharmesh Kheni and jungledev) does not work for me. The image color was off (when setting in IB, it was blue and when setting directly in UIButton, it was black). It turns out I could create the same bar item with the following code:
let barButton = UIBarButtonItem(image: UIImage(named: "menu"), landscapeImagePhone: nil, style: .Done, target: self, action: #selector(revealBackClicked))
self.navigationItem.leftBarButtonItem = barButton
You can use this code for multiple bar button with custom image:
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]
Result will be this:
Initialize barbuttonItem like following:
let pauseButton = UIBarButtonItem(image: UIImage(named: "big"),
style: .plain,
target: self,
action: #selector(PlaybackViewController.pause))
Your problem is because of the way the icon has been made - it doesn't conform to Apple's custom tab bar icon specs:
To design a custom bar icon, follow these guidelines:
Use pure white with appropriate alpha transparency.
Don’t include a drop shadow.
Use antialiasing.
(From the guidelines.)
Something that would be possible looks like this. You can find such icons on most free tab bar icon sites.
Swift 4.
#IBOutlet weak var settingBarBtn: UIBarButtonItem! {
didSet {
let imageSetting = UIImageView(image: UIImage(named: "settings"))
imageSetting.image = imageSetting.image!.withRenderingMode(.alwaysOriginal)
imageSetting.tintColor = UIColor.clear
settingBarBtn.image = imageSetting.image
}
}
SwiftUI
.navigationBarItems modifier takes any view you want:
struct ContentView: View {
var body: some View {
NavigationView {
Text("SwiftUI")
.navigationBarItems(leading:
HStack {
Image(systemName: "trash")
Text("Trash")
}
)
}
}
}
.navigationBarItems(trailing: Image(systemName: "trash") )
.navigationBarItems(leading: Image(systemName: "trash.fill"),
trailing: Image(systemName: "trash")
)
You can use a button for each if you need an action for each of them.
Swift 5+. Smooth solution to add ideal image as you desired dynamic Solution
func rightBarButtonItem(iconNameButton: String, selector: Selector) {
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
button.setImage(UIImage(named: iconNameButton), for: .normal)
button.addTarget(self, action: selector, for: .touchUpInside)
button.imageView?.contentMode = .scaleAspectFit
let buttonBarButton = UIBarButtonItem(customView: UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25)))
buttonBarButton.customView?.addSubview(button)
buttonBarButton.customView?.frame = button.frame
self.navigationItem.rightBarButtonItem = buttonBarButton
}
Just choose Original image option when adding an image to assets in Xcode
If your UIBarButtonItem is already allocated like in a storyboard.
(printBtn)
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
btn.setImage(UIImage(named: Constants.ImageName.print)?.withRenderingMode(.alwaysTemplate), for: .normal)
btn.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handlePrintPress(tapGesture:))))
printBtn.customView = btn
If you have set up your UIBarButtonItem with an image in the storyboard, one small hack to change the renderingMode is to add the following code to your viewDidLoad(). This way you don't have to resort to adding the entire button and image in code.
if let navButton = self.navigationItem.leftBarButtonItem, let buttonImage = navButton.image {
navButton.image = buttonImage.withRenderingMode(.alwaysOriginal)
}
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Left",
style: .plain,target: self, action: #selector(rightbarButtonAction))
navigationItem.rightBarButtonItem?.image = UIImage(named: "Notification Bell")