how to change the navigation back item function ,back to rootView - ios

I have a problem.
I use show(vc) to present a view controller.
vc1 --> vc2 --> vc3
I want to redirect user from vc1 when user clicks on back button on vc3, to achieve that I am using the below mentioned code.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "<", style: UIBarButtonItemStyle.plain, target: self, action: #selector(backToRoot(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
}
func backToRoot(sender: UIBarButtonItem) {
_ = self.navigationController?.popToRootViewController(animated: true)
}
I want the default image of back button, not customized button.
Is there a way I can do that?

I just made this today. I found no way to change action of system back button. In order to look like the system style, I draw a same picture(snapshot the simulator, and change in photo shop). The code is as followed:
let button: UIButton = UIButton(type: .system)
the default size of height is 30, width is whatever you set
button.frame = CGRect(x: 0, y: 0, width: 80, height: 30)
button.setImage(UIImage(named: "BackButton"), for: .normal)
the default font is the following:
button.setTitle("Back", for: .normal)
button.titleLabel?.font = UIFont(name: "AvenirNext", size: 15)
This is the trick, you need find out the same position with the system's, the following is my result, I had adjusted many times. I hope you could use, but I think you need find your own size
button.imageEdgeInsets = UIEdgeInsetsMake(0, -43, 0, 0)
button.titleEdgeInsets = UIEdgeInsetsMake(0, -33, 0, 0)
button.addTarget(target, action: action, for: .touchUpInside)
let barButton = UIBarButtonItem(customView: button)

Related

Positioning view next to navigationTitle [duplicate]

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")

Dismiss Keyboard from Another View Controller

I'm using SJSegmentedViewController to make my view controller segmented.
I have one view controller named as PlaceReviewsVC where I have added textView for review. For post this review I'm adding Post bar button instance of UIBarButtonItem at navigationItem.rightBarButtonItem in my placeDetailSegmentController which are instance of SJSegmentedViewController.
Now issue is when I click on post button, I'm not able to dismiss keyboard.
I have tried following code to add post button in segmented view controller.
let headerVC = PlaceImagesVC.viewController()
let reviewVC = PlaceReviewsVC.viewController()
reviewVC.delegate = self
reviewVC.title = "Reviews"
let placeDetailSegmentController = SJSegmentedViewController()
placeDetailSegmentController.delegate = self
placeDetailSegmentController.title = "Pedal Studio"
placeDetailSegmentController.headerViewController = headerVC
placeDetailSegmentController.segmentControllers = [reviewVC]
placeDetailSegmentController.headerViewHeight = 280
placeDetailSegmentController.selectedSegmentViewHeight = 2.0
placeDetailSegmentController.selectedSegmentViewColor = .white
let button = UIButton(type: .custom)
button.setImage(#imageLiteral(resourceName: "icon_back").withRenderingMode(.alwaysTemplate), for: .normal)
button.tintColor = .white
button.addTarget(self, action:#selector(backButtonTapped), for:.touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
button.contentMode = .scaleAspectFit
button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
let leftButton = UIBarButtonItem(customView: button)
placeDetailSegmentController.navigationItem.leftBarButtonItem = leftButton
let btnPost = UIButton(type: .custom)
btnPost.setTitle("POST", for: .normal)
btnPost.addTarget(self, action:#selector(btnPostTapped), for:.touchUpInside)
btnPost.titleLabel?.setFont(Typography.getFont(.PoppinsMedium, size: 12.0), .white)
btnPost.setTitleColor(.menuColor, for: .normal)
btnPost.setTitleColor(.darkGray, for: .highlighted)
btnPost.contentMode = .scaleAspectFit
let rightButton = UIBarButtonItem(customView: btnPost)
placeDetailSegmentController.navigationItem.rightBarButtonItem = rightButton
self.navigationController?.pushViewController(placeDetailSegmentController, animated: true)
where inside btnPostTapped method I have wrote following code to dismiss keyboard. But didn't work.
#objc func btnPostTapped() {
self.view.endEditing(true)
}
How can I dismiss keyboard from one view controller to another?
You should change your code to dismiss keyboard as follows:
#objc func btnPostTapped() {
AppDelegate.shared.window?.endEditing(true)
}
Our app's base is window, So when you perform any event on window it will affect on whole app. I hope this will fix your issue.
Hide keyboard from anywhere
UIApplication.shared.sendAction(#selector(UIApplication.resignFirstResponder), to: nil, from: nil, for: nil)
or
Get the required viewcontroller instance from navigation hierarchy and resign keyboard as:
requiredViewController.textField.resignFirstResponder()
or
requiredViewController.view.endEditing(true)

Making the nav bar title a button (Swift)

I'm trying to make the title of the nav bar its own button. Users in my app can have multiple profiles, and the nav bar title displays the username of their currently selected profile. Pressing this button should bring up a list of available profiles to choose from (handleShowProfiles). For some reason, the title displays but does not function as a button, it's just static text and touching it does nothing.
let changeProfileContainer : UIView = {
let container = UIView()
container.frame = CGRect(x: 0, y: 0, width: 200, height: 40)
let button = UIButton(type: .custom)
button.setTitle("#username ▼", for: .normal)
button.setTitleColor(.black, for: .normal)
button.frame = container.frame
button.addTarget(self, action: #selector(handleShowProfiles), for: .touchUpInside)
container.addSubview(button)
return container
}()
func configureNavBar() {
self.navigationController?.navigationBar.tintColor = .black
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "send"), style: .plain, target: self, action: #selector(handleSubmitPost))
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "drafts"), style: .plain, target: self, action: #selector(handleDrafts))
self.navigationItem.titleView = changeProfileContainer
}
Any ideas why the button part won't function? In Apple's documentation, it says you have to put the button inside a view, make the button type custom, and change the button's frame from it's default (0, 0, 0, 0). I'm pretty sure this is where I'm messing up but I dunno.
Linked to self invocations in computed property -- See the last portion of Ahmad F's answer
Don't know why, but selectors in computed properties don't seem to work.
I tried adding the container view without computing it and clicking on the button works.
func configureNavBar() {
self.navigationController?.navigationBar.tintColor = .black
let container = UIView()
container.frame = CGRect(x: 0, y: 0, width: 200, height: 40)
let button = UIButton(type: .custom)
button.setTitle("#username ▼", for: .normal)
button.setTitleColor(.black, for: .normal)
button.frame = container.frame
button.addTarget(self, action: #selector(pressTitle), for: .touchUpInside)
container.addSubview(button)
navigationItem.titleView = container
}

RightBarButtonItem is not displayed in the correct location

I am creating a UINavigationController programmatically and add my ViewController to it:
// wrap in a navigation controller
let navigationController = UINavigationController(rootViewController: myViewController)
self.present(navigationController, animated: true, completion: nil)
And then add an image to navigation item:
let backButton: UIBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: target, action: selector)
backButton.image = UIImage(named: "ic_back")
self.navigationItem.rightBarButtonItem = backButton
But my BarButton is not displayed in the correct location. What am I doing wrong?
You need to init UIBarButton directly to UIImage or Custom View:
i.e.,
Swift 3.0:
let image = UIImage(named: "ic_back")?.withRenderingMode(.alwaysOriginal)
let button = UIBarButtonItem(image: image, style: .plain, target: target, action: selector)
self.navigationItem.rightBarButtonItem = button
This will fix your issue.
alloc and init UIButton with desired frame! set image to that button. Set content mode if required! add target on this button to handle click! then alloc and init UIBarButtonItem using initWithCustomView method and pass UIButton as parameter that you have created.
Then set navigationItem's rightBarbuttonItem to this barbutton!
let btn1 = UIButton(type: .custom)
btn1.setImage(UIImage(named: "imagename"), for: .normal)
btn1.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn1.addTarget(self, action: #selector(Class.Methodname), for: .touchUpInside)
let item1 = UIBarButtonItem(customView: btn1)
self.navigationItem.setRightBarButtonItems(item1, animated: true)
You can set the button on navigation bar like this..
let Button = UIButton(frame: CGRect(x: 0, y: 0, width: 35, height: 40))
Button.setBackgroundImage(UIImage(named: "btn.png"), for: .normal)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: Button)
So this code is helps you to achieve your query
Add frame to your backButton using the following code and let us know if it worked.
backButton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
You may change width and height acc. to your need.

How to set image for bar button with swift?

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")

Resources