Change font in UITextInput - ios

I'm trying to develop a keyboard and it should use a different font then the default one. Here's the line:
override func textDidChange(textInput: UITextInput?) {
textInput.font = UIFont(name: "font name", size: 30)
}
But it doesn't work.... How can I fix it?
Thanks.

Follow this steps to use custom Fonts
Drag and drop your font into Xcode
Choose options for adding these files:
Copy items if needed
Create groups
Add to targets:(your app name)
In your Info.plist file add a key named: Fonts provided by application, which is an array
Customize your font:
myUILabel.text = "demoText"
myUILabel.font = UIFont(name: "myCustomFont.ttf", size: 25)

Related

Different fonts for each language using storyboards in iOS application

I'm facing a problem, where I need to use different fonts for each language that my application supports.
For example: I need to use "Arial" for Georgian language and "Times new roman" for English language.
Well, obviously there are lot's of ways solving this problem programmatically, but how this could be done using storyboards?
I have a UILabel on the view controller which is loaded from Storyboard. If I choose "Georgian" language in my iPhone settings >> General >> Language & Region >> PREFERRED LANGUAGE ORDER and open the application, the font of the label should be "Arial", but if I choose "English" language in iPhone settings, label's font should be "Times new roman".
NOTE: There shouldn't be any storyboard outlets to the code for the label.
The only thing doing this that comes to my head is to implement #IBInspectable property as UILabel extension and write some part of the code in it:
extension UILabel {
#IBInspectable var adjustFont: Bool {
get { return false } // we don't care about return value
set { // this is where the game starts
if newValue {
switch systemLanguage {
case .Georgian:
self.font = UIFont(name: "Arial", size: 17)
case .English:
self.font = UIFont(name: "Times new roman", size: 17)
}
}
}
}
}
Well, this is kinda solution but I'm looking more elegant/correct way doing this.
Any help/suggestions would be helpful.
Thank you

iOS using custom Arabic/Cyrillic fonts automatically

I'm trying to learn if it is possible to use a custom Arabic and Cyrillic fonts without having to do a switch/if-else on the user's language setting.
I can successfully use my custom font in the app. I'd like to supply a custom Ar/Cy font the same way, and I know I could build it into the app. If I have my font SpecialFont.otf and also supply SpecialFont-CY.otf how would the OS know to use SpecialFontCY.otf when the user is using a Cyrillic language? Ideally the OS will know the user's primary font and would be able to select a font that matches/includes the correct glyphs for the language.
PS. this is not a question on how to use a custom font, I can do that. I want to know how to supply multiple fonts for various languages to fully support the world without writing code like this:
if NSLocale.preferredLanguages.first == "Arabic"
let myFont = UIFont(name:"SpecialFont-AR", size: 17)
else if NSLocale.preferredLanguages.first == "Russian"
let myFont = UIFont(name:"SpecialFont-CY", size: 17)
...etc
Rather than using a UIFont, you want a UIFontDescriptor. With that you can set the font attribute cascadeList, which tells the system what order to select fonts based on glyph availability (i.e. look in SpecialFont, but if you can't find a glyph for ب, try SpecialFont-CY, and then SpecialFont-AR).
The point of a cascade list is to select the correct font for a given glyph. This way, if a string contains Cyrillic, Arabic, and Latin mixed together, it'll still work fine.
For example:
// Start with your base font
let font = UIFont(name:"SpecialFont", size: 17)!
// Create the ordered cascade list.
let cascadeList = [
UIFontDescriptor(fontAttributes: [.name: "SpecialFont-AR"]),
UIFontDescriptor(fontAttributes: [.name: "SpecialFont-CY"]),
]
// Create a new font descriptor based on your existing font, but adding the cascade list
let cascadedFontDescriptor = font.fontDescriptor.addingAttributes([.cascadeList: cascadeList])
// Make a new font base on this descriptor
let cascadedFont = UIFont(descriptor: cascadedFontDescriptor, size: font.pointSize)
This is covered in detail in Creating Apps for a Global Audience (WWDC 2018).
No you can't, but you can define a simple extension to DRY your code:
extension UIFont {
static func preferred(ofSize size: CGFloat) -> UIFont{
switch NSLocale.preferredLanguages.first {
case "Arabic": return UIFont(name:"SpecialFont-AR", size: size)!
case "Russian": return UIFont(name:"SpecialFont-CY", size: size)!
default: return UIFont.systemFont(ofSize: size) // etc.
}
}
}
Now all you have to do is:
let myFont = UIFont.preferred(ofSize: 17)
You will need to check this somehow in order to determine what is the right language to set.
If you don't want to use if/else syntax, you can use Ternary Conditional Operator.
let myFont = (NSLocale.preferredLanguages.first == "Arabic") ? UIFont(name:"SpecialFont-AR", size: 17) : UIFont(name:"SpecialFont-CY", size: 17)
Or more readable, like this:
let fontName = (NSLocale.preferredLanguages.first == "Arabic") ? "SpecialFont-AR" : "SpecialFont-CY"
let myFont = UIFont(name: fontName, size: 17)

System font renders as Times New Roman on iOS 13

I have some UILabel with the default system font. But when I install my app on iPad or iPhone with iOS 13.1 the fonts change to something like Times New Roman! Why does this happen? I am sure the label's text is Plain and the font is System. How can I fix this issue?
PS: I have downloaded all SF fonts from Apple web site, and still no luck!
I found the solution, the problem comes with detecting the current label's font. I changed:
descriptions.font = UIFont(name: (descriptions.font?.fontName)!, size: 22)
to
descriptions.font = UIFont.systemFont(ofSize: 22)
and problem solved.
Use UIFontDescriptor
I was having the same issue on iOS 13. Fixed it by using fontDescriptor instead of fontName. I have UILabel in my storyboard connected to its view controller via IBOutlet with font as Text Styles - Callout.
#IBOutlet weak var lblText: UILabel!
Below one didn't worked as expected and showing Times New Roman font:
let font = UIFont.init(name: lblText.font.fontName, size: 50.0)!
lblText.font = font
lblText.text = "Times Coding :)"
Solution using UIFontDescriptor:
let font = UIFont.init(descriptor: lblText.font.fontDescriptor, size: 50.0)
lblText.font = font
lblText.text = "Times Coding :)"
This way it will pick the font you set to a label in your storyboard, you don't need to hardcode the font name.
It seems like Apple is pushing to use the initializer with the weightage. Passing it with the name seems to break it ".SFUI-Regular".
The workaround for this is to use the function with weight like this : UIFont(systemFont:UIFont.systemFontSize, weight: .regular).

UIFont returning nil for custom font

I am trying to use the Nunito-ExtraBoldItalic font for my UILabel.
I followed the steps outlined in tutorials and other answers.
Add font to fonts folder. Made sure the target is set to the project.
Add the entry to plist.
Made sure the font is shown in build phase/copy bundle resources. It is shown.
I am using the following code to create a UIlabel:
uiLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 160, height: 50))
let myfont = UIFont(name: "Nunito-ExtraBoldItalic", size: 14)
uiLabel!.font = myfont
uiLabel!.textColor = UIColor(red: CGFloat(51/255.0), green: CGFloat(33/255.0), blue: CGFloat(32/255.0), alpha: CGFloat(100.0))
addSubview(uiLabel!)
But UIFont returns nil.
Postscript name of font is "Nunito-ExtraBoldItalic".
I also tried running the following:
for familyName:String in UIFont.familyNames {
print("Family Name: \(familyName)")
for fontName:String in UIFont.fontNames(forFamilyName: familyName) {
print("--Font Name: \(fontName)")
}
}
My font is not shown.
The font is visible in storyboard and other areas.
I tried using the Nunito-ExtraBoldItalic, Nunito-ExtraBold Italic, Nunito-ExtraBold-Italic as names. None worked.
So I am not sure what the problem is.
Add the font file to the project.
Add "Fonts provided by application" in Info.plist.
<key>UIAppFonts</key>
<array>
<string>CarterOne.ttf</string>
</array>
Make sure the font file is listed in BuildPhase->Copy Bundle Resources.
Make sure the Target Membership is check.
Do a clean build cmd+option+shift+K
You also need to add the font to the .plist file
Please read the following:
https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app
Add the font name to this plist key:
"Fonts provided by application"

Swift NSAttributedString custom fonts

I've read around for different solutions but nothing seems to work. This code creates a nil exception:
[NSFontAttributeName: UIFont(name: "Raleway-SemiBold", size: 16)!]
I have the fonts installed properly and they show up correctly in the app (target is set).
I tried to add the application provided fonts in the plist but nothing happened. I can't edit the items in the array: (they are item0 : string : Raleway-SemiBold.tff).
So basically I'm stuck... Sometimes Swift and Apple environments are great for a programmer, other times (most of the time), they are sooo faulty and need so many workarounds to reach the expected results.
Many thanks in advance for any help.
You're getting an exception because UIFont(name: "Raleway-SemiBold", size: 16) returns nil and you're force-unwrapping it with !.
Instead, use conditional unwrapping:
if let font = UIFont(name: "Raleway-SemiBold", size: 16) {
let attributes = [NSFontAttributeName: font]
// do something with attributes
} else {
// The font "Raleway-SemiBold" is not found
}
You can use UIFont's familyNames() and fontNamesForFamilyName(_:) methods to get the exact string required.
Swift 4
if let font = UIFont(name: "Raleway-SemiBold", size: 16) {
let attributes = [NSAttributedStringKey.font: font]
// do something with attributes
} else {
// The font "Raleway-SemiBold" is not found
}
You Just have to write the correct string name of your font.
Don't write the name that is font file name. (like bodoni-mt-bold.ttf its the file name i have downloaded from any site).
To find out the exact font name follow the image below.
Go to your label select it and go to custom font and then see the name of your custom font in its family. if your custom font name is there then copy that name and past it as a string where u wanna use it. (Note you can't copy font name text you have to write else where then past it)
For Swift 3, here's an update that worked for me:
First you'll set up the font and then create a textAttribute with the NSFontAttributeName:
let font = UIFont(name: "Raleway-SemiBold", size: 16)
textAttribute = [NSFontAttributeName: font as Any, NSForegroundColorAttributeName: UIColor.black]
You can then apply textAttribute to your label, textfield etc.

Resources