I have a UIBarButtonItem defined as follows:
let cardNavButton: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "card")!, style: UIBarButtonItemStyle.Bordered, target: self, action: self.headerCardButtonSelector)
self.navigationItem.rightBarButtonItem = cardNavButton
cardNavButton.tintColor = UIColor.whiteColor()
When the user tapped the button its color changes. How can I define the color which is displayed when the user tapps the button?
The image which is displayed in this button has more than one color but it is displayed in only one color. How can I change that?
You can create UIBarButtonItem with your custom UIButton and set properly colors for states.
let customButton: UIButton = UIButton()
//customize yout custom button
let cardNavButton: UIBarButtonItem = UIBarButtonItem(customView: customButton)
self.navigationItem.rightBarButtonItem = cardNavButton
Supposing "s" is a proper hex value string such as green "00ff00", use this code when you tap the button:
if let num2 = Int(s, radix: 16) {
flamingoBtn.tintColor = UIColor(netHex:num2)
}
else{
flamingoBtn.tintColor = UIColor.blueColor() //fallback to some default color
}
Related
I am using init(title:image:primaryAction:menu:) of a UIBarButtonItem Apple Documentation on a Toolbar with the hope of showing a button with both image and title. Does anyone know why the title does not show?
I am not looking for a custom implementation that can add a UIBarButtonItem with title and image. I have seen plenty on Stackoverflow. I just want to use this initializer if it works.
I have a UITableViewController subclass and I have added this code to the viewDidLoad
navigationController?.isToolbarHidden = false
let barButtonItem = UIBarButtonItem(title: "New Item", image: UIImage(systemName: "plus.circle.fill"), primaryAction: nil, menu: nil)
toolbarItems = [barButtonItem]
My guess is that since public convenience init(title: String? = nil, image: UIImage? = nil, primaryAction: UIAction? = nil, menu: UIMenu? = nil) is a convenience init, and the fact that there is no init that initialize with both title and image, then using both at the same time is not supported. It's merely a convenience on using primaryAction and menu then having title and image.
Try to assign a custom button to your navBar button, declare your button under your controller class:
let myButton = UIButton(type: .system)
now in viewDidLoad set your custom button with title and assign it to navigation bar:
myButton.setImage(UIImage(systemName: "square.and.arrow.up"), for: .normal)
myButton.setTitle(" your text", for: .normal)
myButton.sizeToFit()
myButton.addTarget(self, action: #selector(yourFunctionAction), for: .touchUpInside)
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: myButton)
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.
Hi I saw too many tutorial from stack overflow for how to change backBarButton I change it but when I check I see my image(custom arrow) beside (default arrow blue one ) I see both beside of each other
I mean the back text changed but the arrow doesn't I see my custom arrow beside default iOS arrow I don't know how should I change it to see my custom arrow only ???
for more detail please check this picture to see this problem
HERE
First You need to hide the default back Button , then supply your Custom one. Following code will help you.
self.navigationItem.hidesBackButton = true
let back: UIButton = UIButton(type: UIButtonType.custom)
back.setImage(UIImage(named: "backarrow"), for: UIControlState.normal)
back.frame = CGRect(x: 0, y: 0, width: 22, height: 22)
back.addTarget(self, action: #selector(self.backPressed), for: UIControlEvents.touchUpInside)
let left: UIBarButtonItem = UIBarButtonItem(customView: back)
self.navigationItem.setLeftBarButton(left, animated: true)
self.navigationController?.navigationBar.topItem?.title = ""
func backPressed() {
//Do your menupulation
}
If I understand you correctly you just need to place your button into Navigation Bar and then set your image name into "image" field.
http://take.ms/Rfrtf - here is for example ;)
Solution 1
You can set default back button color's tint color to red .
UINavigationBar.appearance().tintColor = UIColor.red // add this line appdelegate
Solution 2
self.navigationItem.leftItemsSupplementBackButton = YES;
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
or
self.navigationItem.leftBarButtonItems = #[customBackButtonItem];
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 have implemented a SWReveal control on my app. To triger the action I have a UIBarButtonItem with a custom view. Well, everything is working fine, but I have noticed that I can fire the event even when clicking far away from the image (image of about 44px wide...and clicking up to 100px).
I have been searching for a while, and the best solution that I ve found (defining a custom button and instantiating a UIBarButtonItem with "initWithCustomView")
This is my previous code:
UIBarButtonItem *revealButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"reveal-icon"] style:UIBarButtonItemStylePlain target:_revealController action:#selector(revealToggle:)];
self.navigationItem.leftBarButtonItem = revealButtonItem;
And the code with the "solution":
//create the image for your button, and set the frame for its size
UIImage *image = [UIImage imageNamed:#"reveal-icon"];
CGRect frame = CGRectMake(0, 0, image.size.width, image.size.height);
//init a normal UIButton using that image
UIButton* button = [[UIButton alloc] initWithFrame:frame];
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:_revealController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
//finally, create your UIBarButtonItem using that button
UIBarButtonItem* revealButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = revealButtonItem;
With this later code I know I have a correct sized button (I ve set backgroundColor, and checked the correct size of the button), but still firing the action when tapping far away from the button.
¿any ideas?
Thank you in advance.
Try with button.clipsToBounds = YES;, but I have to agree with the other comments, as per Apple's iOS Human Interface Guidelines, every tappable area should be at least 44x44.
the custom view route seems to work for me, but i did find another solution you can try if that's not working for you. it seems like the tappable area only extends as far over until it hits something the user can tap. i have a title view that the user can tap to do something, so the tappable area of my leftbarbuttonitem stops there. but i also tried adding another uiview with userinteractionenabled set to yes just slightly to the right of the leftbarbuttonitem and that seems to stop the area from extending. i was able to use just the two line standard code instead of the custom. not sure if this will work for you or not
It is hard to make uibarbuttonitem touch area override. We can achieve the same using subclassing uinavigationbar.
File-New-CocoaTouch Class-UINavigationBar- Name it.
This is mine:
import UIKit
import Foundation
let navigationItem : UINavigationItem = UINavigationItem()
class CustomNavigationBar: UINavigationBar {
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.redColor()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
override func drawRect(rect: CGRect) {
}
func addUIButtonToUIBarButtonitems(leftButton:UIButton,leftButtonFrame:CGRect,rightButton:UIButton,rightButtonFrame:CGRect)
{
let leftView = UIView(frame: leftButtonFrame)
leftView.addSubview(leftButton)
let leftItem:UIBarButtonItem = UIBarButtonItem(customView: leftView)
navigationItem.leftBarButtonItem = leftItem
let rightView = UIView(frame: rightButtonFrame)
rightView.addSubview(rightButton)
let rightItem:UIBarButtonItem = UIBarButtonItem(customView: rightView)
navigationItem.rightBarButtonItem = rightItem
items = [navigationItem]
}
}
I have a method for setting uibuttons as uibarbuttonitems. On View Controller, I will add two unbuttons and will pass the same to the navigation bar. The frame of the unbutton will be the click area of the respective uibattonitem.
class CustomNavBarVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.styleCustomNavigationBar()
}
func styleCustomNavigationBar() {
self.navigationController?.setNavigationBarHidden(true, animated: false)
let navigationBar : CustomNavigationBar = CustomNavigationBar(frame: CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 64.0))
//menu button
let menubutton: UIButton = UIButton(frame: CGRectMake(0,0,30,30))
menubutton.setImage(UIImage(named: "menu"), forState: UIControlState.Normal)
menubutton.addTarget(self, action: "backButtonDidClicked", forControlEvents: UIControlEvents.TouchUpInside)
//search button
let searchbutton: UIButton = UIButton(frame: CGRectMake(0,0,30,30))
searchbutton.setImage(UIImage(named: "search1x"), forState: UIControlState.Normal)
searchbutton.addTarget(self, action: "backButtonDidClicked", forControlEvents: UIControlEvents.TouchUpInside)
navigationBar.addUIButtonToUIBarButtonitems(menubutton, leftButtonFrame: CGRectMake(0,0,30,30), rightButton: searchbutton, rightButtonFrame: CGRectMake(0,0,30,30))
self.view.addSubview(navigationBar)
}
func backButtonDidClicked()
{
print("CLICK ")
}
}
You can try this button.clipsToBounds = YES;
This may help you.