Changing font color of UIBarButtonItem - swift

I tried to change the font color of the right bar button item to purple, but it still shows up as white. I've consulted this question and this question. How do I fix this?
Code
let sortButton = UIButton(frame: CGRect(x: 0, y: 0, width: 34, height: 15))
sortButton.setTitle("SORT", for: .normal)
sortButton.titleLabel?.tintColor = UIColor.myMusicPurple
sortButton.tintColor = UIColor.myMusicPurple
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: sortButton)
navigationItem.rightBarButtonItem?.tintColor = UIColor.myMusicPurple

This should do the trick (if you have plain text)
let rightBarButtonItem = UIBarButtonItem(title: "Some text", style: .plain, target: self, action: #selector(someAction))
rightBarButtonItem.tintColor = UIColor.myMusicPurple
navigationItem.rightBarButtonItem = rightBarButtonItem

Please try this
sortButton.setTitleTextAttributes([NSAttributedStringKey.foregroundColor : UIColor.white], for: .normal)

Its simple, just create a reference for UIBarButtonItem from Main.stroyboard to corresponding swift file like this,
#IBOutlet var yourBarBtn: UIBarButtonItem!
After that write this line,
yourBarBtn.tintColor = .white //your_color
Thats it!

First, you need to set plain properties then after you can write as like.
#IBOutlet weak var btnGenerate: UIBarButtonItem!
btnGenerate.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.colorBlue], for: .normal)

What about using:
func setTitleColor(UIColor?, for: UIControlState)
Documentation says it sets the color of the title to use for the specified state.
sortButton.setTitleColor( .red, for: .normal)

Related

Swift: UIBarButtonItem with bigger size than UIToolbar

I have a UIToolbar installed on my Viewcontroller on the bottom via Storyboard. I also added a bottom in the Storyboard and now I want to give this bottom a greater height than the toolbar itself.
It should be something like that, but it cannot be a Tabbar but needs to be a Toolbar, as the items on it are purely contextual actions and not top level navigation items (see Apple guidelines here and here):
I tried the following code in my Viewcontroller without success (as mentioned here):
class MyVC: UIViewController {
#IBOutlet var ibOutletForButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
let menuBtn = UIButton(type: .custom)
menuBtn.frame = CGRect(x: 0.0, y: 0.0, width: 20, height: 120)
menuBtn.setImage(UIImage(named:"iconImage"), for: .normal)
menuBtn.addTarget(self, action: #selector(onMenuButtonPressed(_:)), for: UIControlEvents.touchUpInside)
let menuBarItem = UIBarButtonItem(customView: menuBtn)
let currWidth = menuBarItem.customView?.widthAnchor.constraint(equalToConstant: 24)
currWidth?.isActive = true
let currHeight = menuBarItem.customView?.heightAnchor.constraint(equalToConstant: 124)
currHeight?.isActive = true
ibOutletForButton = menuBarItem
}
}
How could I get the button bigger and moved up that it looks like on the image?
One way you could do this is to add the button directly to the UIViewController instead of to the UIToolbar. You have then complete freedom of positioning and sizing.
As you don't use a UITabBar, you will stay within your UIViewController and it should be no problem
You can create 4 BarbuttonItem after first 2, give some flexible space between items and add your 'plus' button to toolbar directly in that space.
#IBOutlet weak var myToolBar: UIToolbar!
let menuBtn = UIButton(type: .custom)
override func viewDidLoad() {
super.viewDidLoad()
let menuBtn = UIButton(type: .custom)
menuBtn.frame = CGRect(x: myToolBar.center.x-10, y: -60, width: 20, height: 120)
menuBtn.setImage(UIImage(named:"iconImage"), for: .normal)
menuBtn.addTarget(self, action: #selector(onMenuButtonPressed(_:)), for: UIControlEvents.touchUpInside)
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let items = myToolBar.items!
myToolBar.setItems([items[0],items[1],spacer,items[2],items[3]], animated: false)
myToolBar.addSubview(menuBtn)
}

Making rightBarButtonItem bold

I am trying to set up a navigation button to appear red and semibold. I managed to changed the color but I'm having trouble changing it to semibold:
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Sign Up", style: .plain, target: self, action: #selector(signIn))
navigationItem.rightBarButtonItem?.tintColor = .red
UIBarItem.appearance().setTitleTextAttributes(
[
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12, weight: .semibold)
],
for: .normal)
I tried rightBarButtonItem.appearance first but that doesn't seem to be an option.
I'm working with Swift 4.2.
You can set the style property to .done to make the UIBarButtonItem bold. This will work until Apple changes how the done button looks in a newer version of iOS.
navigationItem.rightBarButtonItem?.style = .done
Well to have fully customized bar button appearance, you can use bar button items with custom view just like this
let doneButton: UIButton = UIButton (type: UIButton.ButtonType.custom)
doneButton.setTitle("Done", for: .normal)
doneButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
doneButton.setTitleColor(.blue, for: .normal)
doneButton.addTarget(self, action: #selector(self.doneBarButtonTapped(sender:)), for: UIControl.Event.touchUpInside)
doneButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
let barButton = UIBarButtonItem(customView: doneButton)
navigationItem.rightBarButtonItem = barButton

I am trying to create a UIbarButtonItem whose width and height is equal to 70% of the height of the navigationbar?

I am trying to write an extension fo UIBarButtonItem. I would like to use auto layout so that the UIBarButtonItem's width and height is 70% of the height of the UINavigationBar. When I implement this extension, i am getting the following auto layout errors:
import UIKit
extension UIBarButtonItem {
static func menuButton(target: Any?, action: Selector, imageName: String, navigationBar: UINavigationBar) -> UIBarButtonItem{
let button = UIButton.init(type: .system)
let image = UIImage.init(named: imageName)
button.setBackgroundImage(image, for: .normal)
button.addTarget(target, action: action, for: .touchUpInside)
let menuButton = UIBarButtonItem.init(customView: button)
menuButton.customView?.translatesAutoresizingMaskIntoConstraints = false
menuButton.customView?.widthAnchor.constraint(equalTo: navigationBar.heightAnchor, multiplier: 0.7).isActive = true
menuButton.customView?.heightAnchor.constraint(equalTo: navigationBar.heightAnchor, multiplier: 0.7).isActive = true
return menuButton
}
}
Implementation:
let rightButton = UIBarButtonItem.menuButton(target: self, action: #selector(editCells), imageName: "expand", navigationBar: navigationController!.navigationBar)
navigationItem.rightBarButtonItem = rightButton
Error message in console:
Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutDimension:0x600001be1180 "UIButton:0x7ff5d6d16b80.width"> and <NSLayoutDimension:0x600001be25c0 "UINavigationBar:0x7ff5d911a2f0.height"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'
You can create custom view for your navigationBar custom button and set properties for whatever you want like this:
func addRightButton() {
let barButtonView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 180, height: 40)))
barButtonView.backgroundColor = UIColor.red
let navigationBarHeightWithRatio = (navigationController?.navigationBar.frame.height ?? 100) * 0.7
let customBarButton = UIButton(frame: CGRect(x: 0, y: 8, width: navigationBarHeightWithRatio, height: navigationBarHeightWithRatio))
customBarButton.setImage(UIImage(named: "your_image_name"), for: .normal)
customBarButton.setTitle("title", for: .normal)
customBarButton.addTarget(self, action: #selector("<your_action_function>"), for: .touchUpInside)
barButtonView.addSubview(customBarButton)
let rightBarButton = UIBarButtonItem(customView: barButtonView)
navigationItem.rightBarButtonItem = rightBarButton
}
Note:
You can customize width different width, height values and x, y positions.
I hope it is works.
Enjoy.
The error message is clear. When you say:
let rightButton = UIBarButtonItem.menuButton(
target: self, action: #selector(editCells),
imageName: "expand",
navigationBar: navigationController!.navigationBar)
... and the menuButton method runs, at that moment, you are trying to form a constraint relationship between the button and the navigation bar at a time when the button is not in the navigation bar. That, as the error message tells you, is illegal.
(I doubt that the goal you have outlined is possible at all, but that's another story. I'm just explaining the error message.)

Setting font size of UIBarButtonItem

I am creating a UIBarButtonItem with the following code.
let rightItem = UIBarButtonItem(title: "➞", style: UIBarButtonItemStyle.Plain, target: self, action: "navigateToViewTwo")
if let font = UIFont(name: "System", size: 25.0) {
rightItem.setTitleTextAttributes([NSFontAttributeName: font], forState: UIControlState.Normal)}
navigationController?.navigationBar.topItem?.rightBarButtonItem = rightItem
The button should display a right arrow, and it does. The problem is that the font is not controlling the size of the button. I get the following:
The only happens when using the System font. I tried it with Helvetica, and I got the following:
The arrow is definitely larger, but it is also too high on the nav bar. If I rotate the screen, it looks bad.
The arrow is too high, and looks out of place. See how it looks, compared to the Item button on the left? That one was dragged and dropped.
How can I adjust the arrow so that it is in the correct size, and in the correct place on the screen?
You have to set title edge insets
With CustomView
var btn = UIButton.buttonWithType(UIButtonType.System) as! UIButton
btn.frame = CGRectMake(10, 20, 50, 50)
btn.setTitle("➞", forState: UIControlState.Normal)
btn.titleLabel?.font = UIFont(name: "Helvetica" , size: 17)
btn.titleEdgeInsets = UIEdgeInsetsMake(5, 0, 0, 0)
btn.addTarget(self, action: Selector("navigateToViewTwo"), forControlEvents: UIControlEvents.TouchUpInside)
var right = UIBarButtonItem(customView: btn)
With Normal as you have done
var rightItem = UIBarButtonItem(title: "➞", style: UIBarButtonItemStyle.Plain, target: self, action: "navigateToViewTwo")
rightItem.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Helvetica", size: 17.0)!], forState: UIControlState.Normal)
rightItem.setTitlePositionAdjustment(UIOffsetMake(0.0, 5.0), forBarMetrics: UIBarMetrics.Default)
Set both for comparison, just add it which looks batter :
navigationController?.navigationBar.topItem?.rightBarButtonItems = [rightItem,right]
Results :
Hope it will help you.
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : UIColor(red:0.12, green:0.28, blue:0.40, alpha:1.0), NSAttributedStringKey.font: UIFont(name: "GalanoGrotesque-SemiBold", size: 18)!], for: .normal)
I have encounter this problem before, and I decide to use a custom view to handle this as follow:
var view = // create your custom view
var btnMenu = UIBarButtonItem(customView: view)

Setting Background Image for UIBarButtonItem in swift

I am trying set the background image of UIBarButtonItem programatically. But my image is stretched and tiled. Any help on fixing this would be much appreciated. Here is my code
var objectSelected : UIImage!{
didSet{
if objectSelected == nil {
objectSelected = UIImage(named: "line")
}
let insets = UIEdgeInsetsMake(0, 0, 10, 0)
objectSelected.resizableImageWithCapInsets(insets)
objectSelector.setBackgroundImage(objectSelected, forState: UIControlState.Normal, style: UIBarButtonItemStyle.Plain, barMetrics: UIBarMetrics.Default)
}
}
#IBOutlet weak var objectSelector: UIBarButtonItem!
You could try this.
var myBtn: UIButton = UIButton()
myBtn.setImage(UIImage(named: "line"), forState: .Normal)
myBtn.frame = CGRectMake(0, 0, 70, 70)
myBtn.addTarget(self, action: "myBtnAction:", forControlEvents: .TouchUpInside)
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: myBtn), animated: true)