Error when instantiating a UIFont in an text attributes dictionary - ios

I'm trying to set the font of the UIBarButtonItem like so:
let barButton = UIBarButtonItem.appearance()
barButton.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "AvenirNext", size: 15], forState: UIControlState.Normal)
But it throws a compiler error saying:
Cannot invoke 'init' with an argument list type '($T7, forState: UIControlState)`
and I have no idea what that means. I have also tried
barButton.titleTextAttributesForState(UIControlState.Normal) =[NSFontAttributeName...]`
but it appears that it isn't assignable
How can I resolve this?

The initializer of UIFont returns an optional because it may fail due to misspelled font name etc.
You have to unwrap it and check:
if let font = UIFont(name: "AvenirNext", size: 15) {
barButton.setTitleTextAttributes([NSFontAttributeName: font], forState: UIControlState.Normal)
}
UPDATED for Swift 3
if let font = UIFont(name: "AvenirNext", size: 15) {
barButton.setTitleTextAttributes([NSFontAttributeName:font], for: .normal)
}

Setting Custom font is little bit tricky, since they don't have font and title properties. Hope this following answer will help you.
let font = UIFont(name: "<your_custom_font_name>", size: <font_size>)
var leftBarButtonItem = UIBarButtonItem(title: "<font_hex_code>", style: UIBarButtonStyle.Plain, target: self, action: "buttonClicked:")
leftBarButtonItem.setTitleTextAttributes([NSFontAttributeName:font!], forState: UIControlState.Normal)
self.navigationItem.leftBarButtonItem = leftBarButtonItem

if let font : UIFont = UIFont(name: "Roboto-Regular", size: 15)
{
cancelBarButton.setTitleTextAttributes([NSFontAttributeName: font], forState: UIControlState.Normal)
doneBarButton.setTitleTextAttributes([NSFontAttributeName: font], forState: UIControlState.Normal)
}

With Swift 4
NSFontAttributeName is deprecated, you can use NSAttributedStringKey values to set attributes.
if let fontStyle = UIFont(name: "HelveticaNeue-Light", size: 19) {
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.font: fontStyle]
}

Related

Font of barButtonItem changes when highlighted swift 4.2

I have a barbuttonItem here:
let doneBarButtonItem: UIBarButtonItem? = {
let barButtonItem = UIBarButtonItem()
barButtonItem.setTitleTextAttributes([
NSAttributedString.Key.font : UIFont(name: "Avenir-Heavy", size: 12)!,
NSAttributedString.Key.foregroundColor : UIColor.black,
], for: .normal)
barButtonItem.title = "DONE"
return barButtonItem
}()
Yet when i press on it, it changes to a different font. What is the property to change the font when highlighted? Thank you.
barButtonItem.setTitleTextAttributes([
NSAttributedString.Key.font : UIFont(name: "Avenir-Heavy", size: 12)!,
NSAttributedString.Key.foregroundColor : UIColor.black,
], for: .highlighted) // This line

Change the font on the back button of a navigation controller under swift 4

Swift 4, iOS 11.2.5 Xcode 9.2
Trying to change the font of the back button. Tried previous solutions found, but none seem to work under Swift 4, iOS 11.2.5 with my configuration, navigation controller within a tab bar controller.
Got this code, the first and last lines work, but the center three do not.
self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!]
navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .normal)
navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .highlighted)
navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .focused)
navigationItem.title = "Filter \(titleSelection!) [shake to clear]"
This is in viewDidLoad method. Should this work?
For Swift 4, U can try this in AppDelegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red, NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 15)!], for: UIControlState.normal)
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.green, NSAttributedStringKey.font : UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)! ], for: .highlighted)
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.blue, NSAttributedStringKey.font : UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)! ], for: .focused)
return true
}
In ViewController.
override func viewWillAppear(_ animated: Bool) {
self.title = "List"
self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!]
// THE BELOW THREE LINES NOT WORKING.
//navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .normal)
//navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .highlighted)
//navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .focused)
}
Storyboard
Output
You could change the font in the app delegate by doing something along these lines, this will change the font through out the whole app instead of in one viewcontroller though.
if let customFont = UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20.0) {
UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName: customFont], for: .normal)
}
To make it working on iOS 13.0 you should use UINavigationBarAppearience. Here is what you can do in order to change font of ALL elements in the navigation bar:
if #available(iOS 13.0, *) {
let navBarAppearance = UINavigationBarAppearance()
let attributes = [NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!]
navBarAppearance.titleTextAttributes = attributes
navBarAppearance.buttonAppearance.normal.titleTextAttributes = attributes
navBarAppearance.doneButtonAppearance.normal.titleTextAttributes = attributes
self.navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
self.navigationController?.navigationBar.standardAppearance = navBarAppearance
}
Instead of:
navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .normal)
Try:
self.navigationController?.navigationBar.topItem?.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "AvenirNextCondensed-DemiBoldItalic", size: 20)!], for: .normal)
In Swift 5 you can do it by these:
let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17, weight: .regular)]
self.navigationItem.backBarButtonItem?.setTitleTextAttributes(attributes, for: .normal)
Please note it will be effective for the next pushed view controller not the current one on the display, that's why it's very confusing!
Also, check the storyboard and select the navigation item of the previous view controller then type something in the Back Button (Inspector).

Swift change font and color of back button

I am developing an app in Swift 2.2. Now I want to change the back button font and color for a certain view. The view in question has a navigation controller as it's parent controller.
I've tried running both of the following lines in viewDidLoad of my ViewController
self.navigationController!.navigationItem.backBarButtonItem!.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Andes Rounded", size: 17)!], forState: .Normal)
self.navigationItem.backBarButtonItem!.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Andes Rounded", size: 17)!], forState: .Normal)
Neither throws any errors, but it doesn't make any difference to the back button. I've also tried running both of these
self.navigationController!.navigationItem.leftBarButtonItem!.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Andes Rounded", size: 17)!], forState: .Normal)
self.navigationItem.leftBarButtonItem!.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Andes Rounded", size: 17)!], forState: .Normal)
This however throws an error (error unwrapping nil). How should I change the font and color of the nav bar back button correctly? Feels like I'm not modifying the right items...
If you want to set same color to bar buttons implicitly then in your AppDelegate, in didfinishlaunchingwithoptions, write:
UINavigationBar.appearance().tintColor = UIColor.white //your desired color here
Update :
Put this in AppDelegate,
UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Andes Rounded", size: 17)!], forState: .Normal) // your textattributes here
Update 2 :
UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([UINavigationBar.classForCoder()]).setTitleTextAttributes(["attribute" : "value"], forState: .Normal)
Hope this will help :)
Swift 3.0 answer (based on Lion's answer):
let newFont = UIFont(name: "Avenir Next", size: 16.0)!
let color = UIColor.white
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.classForCoder() as! UIAppearanceContainer.Type]).setTitleTextAttributes([NSForegroundColorAttributeName: color, NSFontAttributeName: newFont], for: .normal)
Works a treat, for those that have already managed to customise other parts of their nav bars but not the back button!
I think you should change it in the vc before your actual vc. Look at: UINavigationItem
Edit:
For example you can write:
let item = UIBarButtonItem(title: "Text goes here", style: .Plain, target: self, action: #selector(self.navigationController?.popViewControllerAnimated(_:)))
item.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Helvetica-Bold", size: 23)!], forState: .Normal)
navigationItem.backBarButtonItem = item
in your prepareForSegue Method.
Swift 4
in AppDelegate.swift
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "Helvetica-Bold", size: 15)!], for: .normal)
in swift 4.2
to change back button color
self.navigationController?.navigationBar.tintColor = .white
Use the following code:
navigationController?.navigationBar.barTintColor = UIColor.purpleColor()
navigationController?.navigationBar.tintColor = UIColor.whiteColor()
change colour according to your need
create custom button and make it as you want and add action to go back.
func addBackBarButtonOnNavigationBar(){
// add image here
let searchImage:UIImage = UIImage(named: "back button image")!
var backBtn:UIBarButtonItem = UIBarButtonItem(image: searchImage, style: UIBarButtonItemStyle.Plain, target: self, action: #selector(classname.buttonActionMethodName(_:)))
backBtn.tintColor = UIColor.lightGrayColor()
if let font = UIFont(name: "AvenirNext", size: 15) {
backBtn.setTitleTextAttributes([NSFontAttributeName: font], forState: UIControlState.Normal)
}
self.navigationItem.leftBarButtonItem = backBtn
}
func buttonActionMethodName(){
self.navigationController!.popViewControllerAnimated(true)
}
In Swift 5 you can do it by these:
self.navigationItem.backBarButtonItem?.tintColor = UIColor.red
let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17, weight: .regular)]
self.navigationItem.backBarButtonItem?.setTitleTextAttributes(attributes, for: .normal)
Please note it will be effective for the next pushed view controller not the current one on the display, that's why it's very confusing!
Also, check the storyboard and select the navigation item of the previous view controller then type something in the Back Button (Inspector).

left and right barButtons font in UIImagePickerController

What is the way to set custom font to left and right UIBarButtons of the UIImagePickerController?
I've tried this code but it doesn't work:
let imagePicker = UIImagePickerController()
imagePicker.navigationBar.barTintColor = UIColor(hex: 0x212121)
imagePicker.navigationBar.translucent = false
imagePicker.navigationBar.tintColor = UIColor.whiteColor()
imagePicker.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont(name: "Roboto-Regular", size: 20.0)!]
// doesn't work
imagePicker.navigationItem.backBarButtonItem?.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont(name: "Roboto-Regular", size: 25.0)!], forState: UIControlState.Normal)
imagePicker.navigationItem.leftBarButtonItem?.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont(name: "Roboto-Regular", size: 20.0)!], forState: UIControlState.Normal)
imagePicker.navigationItem.rightBarButtonItem?.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont(name: "Roboto-Regular", size: 20.0)!], forState: UIControlState.Normal)
you are going to need to subclass UIImagePickerController and set your own tool bar.
There is a great example from apple: https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html
It's in objective-C but I'm sure it will give you an idea of what you need to do.

Appearance Proxy in Swift (iOS)

Has anyone tried using the appearance proxy in swift yet?
This syntax doesn't work, has anyone figured out how to set title text attributes on controls like segmentedControl or UITabBar? I think I am close
segmentedControl.titleTextAttributesForState(UIControlState.Normal) =
NSDictionary(objects: [UIFont(name: fontFamilyRegular, size: 16.0)],
forKeys: [NSFontAttributeName])
This should do it:
segmentedControl.setTitleTextAttributes([
NSFontAttributeName: UIFont(name: "Helvetica", size: 16.0)!,
NSForegroundColorAttributeName: UIColor.blueColor()
], forState: UIControlState.Normal)
Make sure you unwrap the the font (!)
let font = UIFont(name: "HelveticaNeue-Light", size:15.0)!
UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName:font,NSForegroundColorAttributeName:UIColor.redColor()], forState: UIControlState.Normal)
For XCode 6.1, try this:
UITabBarItem.appearance().setTitleTextAttributes(NSDictionary(object: UIFont(name: "Helvetica", size: 16.0)!, forKey: NSFontAttributeName), forState: UIControlState.Normal)

Resources