I am building an e-commerce application that has shopping cart in rightBarButtonItem.I have implemented extension to add shopping cart barButtonItem in every UIViewControllers.My barButtonItem is showing properly in simulator devices ( including iPhone 6s,iPhone SE and iPhoneX simulators ).But it is not showing on my physical device ,iPhone 6s.Could anyone help me how to trace this issue?? Thanks for your attention
Here is my code
extension UIViewController{
func addCartBarButtonItem(){
let cartButton = UIButton(type: .custom)
cartButton.setImage(UIImage(named:"cart"), for: .normal)
cartButton.widthAnchor.constraint(equalToConstant: 28.0).isActive = true
cartButton.heightAnchor.constraint(equalToConstant: 28.0).isActive = true
cartButton.addTarget(self, action: #selector(self.goCheckOutController), for: .touchUpInside)
let cartBarButtonItem = UIBarButtonItem(customView: cartButton)
cartBarButtonItem.addBadge(number: CartDataManager.loadItems().count)
self.navigationItem.rightBarButtonItem = cartBarButtonItem
}
}
Try this,
var rightSearchBarButtonItem : UIBarButtonItem?
func addCartButtonToNavigationBar(){
self.rightSearchBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "cart") , style: UIBarButtonItemStyle.plain, target: self, action: #selector(goCheckOutController))
self.navigationItem.rightBarButtonItem = self.rightSearchBarButtonItem;
}
This code is working for me
Related
In our app we are showing a burger item in the UINavigationBar.
We are using the leftBarButtonItem as the place to show it.
Here is the code to create the burger button.
let barItem = UIBarButtonItem(image: UIImage(named: "IconBurger"), style: .plain, target: target, action: selector)
barItem.tintColor = .tintColor
barItem.adjustAccessibility()
Which leads to following result on iOS 11.4 and iOS 11.3.1
iOS11.4
iOS10.3.1
As you can see the burger button somehow shrinked on iOS11.4
I fixed this by creating a custom button view like this:
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "IconBurger"), for: .normal)
button.addTarget(target, action: selector, for: .touchUpInside)
let barItem = UIBarButtonItem(customView: button)
barItem.tintColor = .tintColor
barItem.adjustAccessibility()
Using this version the burger button is looking good on iOS 11.4 again.
But now when going back to 10.3.1 I was shocked because the burger button was not rendered at all anymore.
(Imagine completely black image here)
I ended up writing ugly stuff like
if #available(iOS 11.4, *) {
// show new version
} else {
// show old version
}
But I hope that can't be it!
Does anybody experienced similar or can give advise ?
Additional information: We are using pdf assets for creating UIImages in our project.
Ok. Colleague of mine found the solution which I want to document here.
Turns out calling sizeToFit() was missing on < iOS11
let button = UIButton(type: .custom)
let image = UIImage(named: "IconBurger")
button.setImage(image, for: .normal)
button.addTarget(target, action: selector, for: .touchUpInside)
button.sizeToFit()
let item = UIBarButtonItem(customView: button)
item.adjustAccessibility()
return item
I'd like to be able to change only the text color of the back button in the navigation bar.
As a work around, I can sort of do what I'm trying to do by creating a custom view and assigning it to navigationItem.leftBarButtonItem, but it doesn't look very good and I also lose the swipe to pop ability.
Code for the above:
let button = UIButton(type: .system)
let originalImage = #imageLiteral(resourceName: "BackButton")
let scaledImage: UIImage = UIImage(cgImage: originalImage.cgImage!, scale: 30, orientation: originalImage.imageOrientation)
button.setImage(scaledImage, for: .normal)
button.setTitle("YourTitle", for: .normal)
button.sizeToFit()
button.setTitleColor(.brown, for: .normal)
button.tintColor = .blue
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
I also see things suggested like setting attributes of the back button via
navigationController?.navigationBar.topItem.backBarButtonItem?.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.red], for: .normal)
but that doesn't seem to have any effect on the look of the text, despite
print("Attributes: ", navigationController?.navigationBar.topItem?.backBarButtonItem?.titleTextAttributes(for: .normal) ?? "No attributes")
resulting in Attributes: ["NSColor": UIExtendedSRGBColorSpace 1 0 0 1].
I could set tintColor but that would change the color of the back icon in addition to the title.
So what's the best way to do what I want? Is there a way?
Am not sure whether I understood you correctly. But try the below code. This will apply to all the bar button items of your app. Place this code where it is called only once though out app lifecycle. Like application: didFinishLaunchingWithOptions:
let attribs = [NSForegroundColorAttributeName: UIColor.red, NSFontAttributeName: UIFont.boldSystemFont(ofSize: 18)]
UIBarButtonItem.appearance().setTitleTextAttributes(attribs, for: .normal)
I figured it out. You can style the back button by setting self.navigationItem.backBarButtonItem in the previous view controller.
For example, in my case I had TableViewController and when you clicked on a cell, the app would transition to ViewController. In TableViewController I had
public func changeColor() {
let barButton = UIBarButtonItem(title: "Anything", style: .plain, target: nil, action: nil)
barButton.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.brown], for: .normal)
self.navigationItem.backBarButtonItem = barButton
}
and then in ViewController I had
#IBAction func buttonPressed(_ sender: Any) {
let vc = self.navigationController?.viewControllers[0] as! TableViewController
vc.changeColor()
self.title = "hello very long title asdfasdfasfdasdfasdfasdfasdfasdf"
}
As a result, pressing a button in ViewController would change the color of the title of its back button to brown.
Please take a look at my screenshot, the blue "Back" text always show on iphone plus (6s plus, 7 plus for both simulator and real device) . It does not show on smaller screen iphone. I tried lot of way to hide/change it from present/previous controller but no luck.
So why does it work on smaller iphone but not the plus one ?
Can anyone help me:(. Thanks.
Here is the code:
#IBAction func filter(_ sender: Any) {
let view:FilterViewController = self.storyboard?.instantiateViewController(withIdentifier: "FilterViewController") as! FilterViewController
view.superVC = self
view.currentFilter = currentFilter
self.setLeftCloseNavigation()
self.navigationController?.pushViewController(view, animated: true)
}
func setLeftCloseNavigation(){
self.navigationController?.navigationBar.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.layer.mask = nil
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "icon_close")?.withRenderingMode(.alwaysOriginal)
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "icon_close")?.withRenderingMode(.alwaysOriginal)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
And here is the viewDidLoad in pushed controller:
override func viewDidLoad() {
super.viewDidLoad()
statusBar = UIColor.black
setResetNavigation() }
func setResetNavigation(){
navigationItem.hidesBackButton = false
let skipButton = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 30))
skipButton.setTitle("Reset all".localized(), for: .normal)
skipButton.setTitleColor(UIColor.black, for: .normal)
skipButton.titleLabel?.font = UIFont(name: "HJGothamMedium", size: 16)
skipButton.addTarget(self, action: #selector(resetAllClicked), for: .touchUpInside)
let skip = UIBarButtonItem(customView: skipButton)
navigationItem.rightBarButtonItem = skip
}
This is the view hierarchy
Add this function :
override func viewDidAppear(_ animated: Bool) {
setResetNavigation()
self.navigationController?.navigationBar.backItem?.title = ""
}
try this
self.navigationItem.hidesBackButton = true
Or Check your storyboard it will remain
Use the below line to remove the text
navigationController?.navigationBar.topItem?.title = ""
You can inspect your UI hierarchy and if found related view then remove that view :
You can also invoke the view debugger by choosing View UI Hierarchy from the process view options menu in the debug navigator, or by choosing Debug > View Debugging > Capture View Hierarchy.
To hide the back text you need to set navigation item title to space character on the view controller that pushes the presented view controller:
self.navigationItem.title = " "
Be aware you have to set it on the previous view controller and not on top most one. Also you have to set a space character and not an empty string !!!
Also you can do this directly on storyboard
From below code you can set backButton text colour to any colour you want.You can simply set backButton to clear textColor. So, It won't be visible when it presents.
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.classForCoder() as! UIAppearanceContainer.Type]).setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
Update: If you want to go for a different approach.Check this post How to customize the navigation back symbol and navigation back text? and accepted answer.
I have made a custom bar button item at my navigation controller and it was working fine but it doesn't anymore.
This is the lines that I use to make the custom bar button :
func addSlideMenuButton(){
let btnShowMenu = UIButton(type: UIButtonType.Custom)
//btnShowMenu.setImage(self.defaultMenuImage(), forState: UIControlState.Normal)
btnShowMenu.setImage(UIImage(named: "barBtnMenu"), forState: UIControlState.Normal)
btnShowMenu.frame = CGRectMake(0, 0, 30, 30)
btnShowMenu.addTarget(self, action: "onSlideMenuButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
let customBarItem = UIBarButtonItem(customView: btnShowMenu)
// self.navigationItem.rightBarButtonItem = customBarItem;
self.navigationItem.leftBarButtonItem = customBarItem;
}
the image exists and there is no error or crash .
Even If I add the bar button item from soryboard , When I run the application it would hidden my bar button item.
What could be wrong ?
func addSlideMenuButton() {
let customBarItem = UIBarButtonItem(image: UIImage(named: "barBtnMenu"), style: .Plain, target: self, action: "onSlideMenuButtonPressed")
self.navigationItem.leftBarButtonItem = customBarItem;
}
A couple of options come to mind
Are you sure you're not setting navigationItem.hidesBackButton = true anywhere in that UIViewController?
Are you sure you're not adding another UINavigationBar on top of the one provided by the system?
I want to use some of default iOS icons i.e.
in navigation bar.
Basically I don't know how to call image of that item (directly from native library - I know how to download it and place as custom image:)):
var myButton:UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
myButton.addTarget(self, action: "reload", forControlEvents: UIControlEvents.TouchUpInside)
myButton.setImage(???, forState: <#UIControlState#>)
You can use UIBarButtonSystemItem this way:
let button = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Refresh, target: self, action: "someAction")
navigationItem.leftBarButtonItem = button
Result for leftBarButtonItem:
If you want to set it at right side you can use this code:
navigationItem.rightBarButtonItem = button
Result for rightBarButtonItem:
Swift: These are the most commonly used options:
To Use custom image with original colour:
let customImageBarBtn1 = UIBarButtonItem(
UIImage(named: "someImage.png").withRenderingMode(.alwaysOriginal),
style: .plain, target: self, action: #selector(handleClick))
To Use custom image with tint colour:
let customImageBarBtn2 = UIBarButtonItem(
UIImage(named: "someImage.png").withRenderingMode(.alwaysTemplate),
style: .plain, target: self, action: #selector(handleClick))
Or use system provided buttons:
let systemBarBtn = UIBarButtonItem(
barButtonSystemItem: .search,
target: self, action: #selector(handleClick))
Then add any one of these buttons to the navigationItem:
navigationItem.leftBarButtonItems = [customImageBarBtn1, customImageBarBtn2]
navigationItem.rightBarButtonItems = [systemBarBtn]
// OR you can use this if there's only one item.
navigationItem.rightBarButtonItem = systemBarBtn
For custom Images: As a starting size, 22ptx22pt images work well for the default iPhone Navigation Bar size.
In swift 4.3
let btnRefresh = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.refresh, target: self, action: #selector(targeted function to invoke))
//If you want icon in left side
navigationItem.leftBarButtonItem = btnRefresh
//If you want icon in right side
navigationItem.rightBarButtonItem = btnRefresh