UIFont - how to get system thin font - ios

UIFont has methods to get regular font (systemFontOfSize) or bold font (boldSystemFontOfSize), but how to get a "thin system font" available through storyboard?
Passing "system-thin" to UIFont Contructor doesn't work, this constructor only works for non system fonts.

You can use system font thin weight:
UIFont.systemFont(ofSize: 34, weight: UIFontWeightThin)
List of available weights for San Francisco:
UIFontWeightUltraLight
UIFontWeightThin
UIFontWeightLight
UIFontWeightRegular
UIFontWeightMedium
UIFontWeightSemibold
UIFontWeightBold
UIFontWeightHeavy
UIFontWeightBlack
As of iOS 11, UIFontWeight* was renamed to UIFont.Weight.*. More you can get here https://developer.apple.com/documentation/uikit/uifont.weight.

As of iOS 8.2, you can now use UIFont.systemFontOfSize(_ fontSize: CGFloat, weight weight: CGFloat):
UIFont.systemFontOfSize(19, weight: UIFontWeightLight)
iOS SDK provided constants for weights:
UIFontWeightUltraLight
UIFontWeightThin
UIFontWeightLight
UIFontWeightRegular
UIFontWeightMedium
UIFontWeightSemibold
UIFontWeightBold
UIFontWeightHeavy
Using system font is better than creating a font based on font name when you want to use system fonts since iOS can change their system fonts on iOS (like when they did with Helvetica Neue in iOS 7, and now, San Francisco in iOS 9).
So what I would suggest is to include TTF file of the font you want as use that ttf file as custom font and use the custom font in your app.
This is the special reason why I don't like Apple. Never go what Apple say. Always do what we want. Apple keep on changing Default font for every OS.

Also if you want to keep same font size and just change weight then use from targeted element font size. For example:
demoLabel.font = UIFont.systemFont(ofSize: demoLabel.font.pointSize, weight: UIFontWeightThin)
with this you can keep default label font size and just change weight.
As of iOS 11, UIFontWeightThin was renamed to UIFont.Weight.thin. More you can get here https://developer.apple.com/documentation/uikit/uifont.weight.

Swift 4.2 / Swift 5.0
label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.thin)

Related

UIFont render result is different from what we see on Sketch/Figma

I'm working with a designer that is sharing assets coming from Figma and Sketch.
If I use the same exact font size available on Figma/Sketch for my UILabel, I see the rendered fonts are smaller than the same fonts rendered on Figma/Sketch.
I'm using something like this to initialise my font for the labels:
self.font = UIFont(name: "MyFont-Bold", size: 14)
Both Figma and Sketch work in points the same is true for UIFont...
Is there anything we can do to align our results?
For me, this option works well.
UIFont(name: "Font-Name", size: UIScreen.main.bounds.height*(fontSize)/800)

Make selected string of text view Bold, Italic, Underline like native "Notes" app of iOS

Is there any help to make selected string of text view Bold, Italic, Underline like native "Notes" app of iOS. Please give me helpful links. I am tired of searching for the whole day. Many Thanks.
I have attached my code, to make attributed string Bold and Italic both like native app of iPhone "Notes".
attributedString.beginEditing()
attributedString.addAttributes([NSFontAttributeName: UIFont.boldSystemFont(ofSize: CGFloat(app_delegate.settings.chatFontSize))], range: range)
attributedString.addAttributes([NSFontAttributeName: UIFont.italicSystemFont(ofSize: CGFloat(app_delegate.settings.chatFontSize))], range: range)
attributedString.endEditing()
But its giving only Italic string, not also Bold. I need both Italic and Bold. Thanks.
The problem in your code is that you are setting the italic font and overwriting the bold one you've just set. What you need is to use UIFontDescriptor with Symbolic Traits as you can see in this SO answer. So just initialize your system font, get its font descriptor and add traitBold and traitItalic to it. Then you just need to initialize your new Font using UIFont initializer init(descriptor: UIFontDescriptor, size pointSize: CGFloat):
Swift 4 code:
attributedString.beginEditing()
let systemFont: UIFont = .systemFont(ofSize: 32)
if let descriptor = systemFont.fontDescriptor.withSymbolicTraits([.traitBold, .traitItalic]) {
let systemFontBoldAndItalic = UIFont(descriptor: descriptor, size: 32)
attributedString.addAttributes([.font: systemFontBoldAndItalic, .underlineStyle: NSUnderlineStyle.styleSingle.rawValue], range: NSRange(location: 0, length: attributedString.length))
}
attributedString.endEditing()
Take a look at NSAttributedString. You can use that to create strings that have mixed attributes at different ranges.
In Objective-C, the mutable version, NSMutableAttributedString has methods like setAttributes(_:range:) that let you change the attributes of an attributed string in a specified range.
So you'd initialize an NSMutableAttributedString starting from a normal String object, and then use setAttributes(_:range:) function to set different attributes like Bold, Italic, etc on a range of the string.
(No, I don't have sample code handy.)
Although the question is old but it may helps someone.
Using NSMutableAttributedString won't solve the problem, because if you type any where before the customised text the range will be different. Therefore, the customisation will shift to satisfy the updated range.
I think using HTML is better solution if you would have a very long string.
You may consider using some open source libraries, like ZSSRichTextEditor
Hope that help.

iOS Prevent timer UILabel 'shaking' when numbers change

I have a UILabel which shows the output of a timer in the format MM:ss:SS (minutes, seconds, centiseconds), however it "shakes" from left to right as the width of the centiseconds changes - "11" is narrower than "33" for example.
Is there any way I can mitigate this? I've tried centring it, giving it a fixed width but they haven't seemed to help.
Since iOS 9.0, the system font uses proportional digits. If you want monospaced digits, there's a variant font which you can obtain using +[UIFont monospacedDigitSystemFontOfSize:weight:]. This only works for the system font.
If you want to work with another font, you try to ask for a monospaced variant, but there may not be one. Given a UIFont, you can request its fontDescriptor, then ask that for a similar font descriptor that's monospaced (not just for digits) using -[UIFontDescriptor fontDescriptorWithSymbolicTraits:] and UIFontDescriptorTraitMonoSpace. You can then create a new font by passing the new font descriptor to +[UIFont fontWithDescriptor:size:].
However, I doubt there's a monospace variant of Impact. It's not suitable for your purpose.
I had the same problem. #KenThomases answer works. Here's the Swift version:
// replace whatever font your using with this font instead to stop the shaking
UIFont.monospacedDigitSystemFont(ofSize: 19, weight: UIFont.Weight.regular)
ie:
yourLabel.font = UIFont.monospacedDigitSystemFont(ofSize: 19, weight: UIFont.Weight.regular)
FYI there are other UIFont.Weight weights:
.black, .bold, .heavy, .light, .medium, .regular, .semibold, .thin, .ultraLight
According to this other answer the fonts below are system generated fonts that are also monospaced so they won't shake either:
Courier
Courier-Bold
Courier-BoldOblique
Courier-Oblique
CourierNewPS-BoldItalicMT
CourierNewPS-BoldMT
CourierNewPS-ItalicMT
CourierNewPSMT
Menlo-Bold
Menlo-BoldItalic
Menlo-Italic
Menlo-Regular
ie:
// no shaking
yourLabel.font = UIFont(name: "Menlo-Regular", size: 19)
If your using just numeric digits then HelveticaNeue is also monospaced and it doesn't shake but it's questionable. Read the comments below this answer before using this font.
ie:
// no shaking but apparently you can only use numbers not letters
yourLabel.font = UIFont(name: "HelveticaNeue", size: 19)
Use A monospaced font, also called a fixed-pitch, fixed-width, or non-proportional font, is a font whose letters and characters each occupy the same amount of horizontal space. Examples of monospaced fonts include Courier, Courier New, Lucida Console, Monaco, and Consolas

Change Label Font to Bold and Italic objective c

I have created a studio for user to create different type of logos. It also contains a couple of labels. I want to allow the user to convert those label font to bold and italic but I am having an issue that the fonts I am using dont have either Italic or Bold in their families. I tried a couple of solutions which contains:
UIFontDescriptor * fontD = [font.fontDescriptor
fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
selectedLabel.font = [UIFont fontWithDescriptor:fontD size:0];
but this changes my font to system font as no bold or italic font is found to it.
For Bold, I added some stroke so the font looks like bold which is ofcourse a bad practice but then again I got stuck for Italic. Is there any proper way that I can allow those fonts to be converted to Bold and Italic without having bold or italic in their family ?
Fonts I am using Aaargh, Average Sans, Cardinal, Comfortaa and others.

User friendly UIFont `fontNamesForFamilyName:`

If I run this code (on the iPhone):
NSArray *names = [UIFont familyNames];
NSLog(#"Font FamilyNames");
for (NSString *name in names) {
NSLog(#"Font Family: %#",name);
NSArray *fontFaces = [UIFont fontNamesForFamilyName:name];
for (NSString *fname in fontFaces) {
NSLog(#" %#",fname);
}
}
I get this output (abridged):
...
Font Family: Georgia
Georgia-BoldItalic
Georgia-Bold
Georgia-Italic
Georgia
Font Family: Helvetica Neue
HelveticaNeue-BoldItalic
HelveticaNeue-Light
HelveticaNeue-Italic
HelveticaNeue-UltraLightItalic
HelveticaNeue-CondensedBold
HelveticaNeue-MediumItalic
HelveticaNeue-Thin
HelveticaNeue-Medium
HelveticaNeue-ThinItalic
HelveticaNeue-LightItalic
HelveticaNeue-UltraLight
HelveticaNeue-Bold
HelveticaNeue
HelveticaNeue-CondensedBlack
Font Family: Gill Sans
GillSans
GillSans-Italic
...
You can see that each font family has various fonts, but the font names are anything but user-friendly. For example, TextEdit presents them in a much better way:
How can I in a stable way (meaning it works on all fonts, even fonts not yet available on iOS) get the names for each font like TextEdit?
The only thing that comes to mind is to parse each font face name, turning HelveticaNeue-CondensedBold into Condensed Bold and HelveticaNeue-UltraLightItalic into Ultra Light Italic. However, you'll notice that TextEdit presents HelveticaNeue-UltraLightItalic as UltraLight Italic, not Ultra Light Italic and I'm not sure this method works for all fonts...
Examples of fonts that would not work well with my idea:
Font Family: Bodoni 72
BodoniSvtyTwoITCTT-Book
BodoniSvtyTwoITCTT-Bold
BodoniSvtyTwoITCTT-BookIta
(Bodoni 72 != BodoniSvtyTwoITCTT)
Font Family: Times New Roman
TimesNewRomanPS-BoldItalicMT
TimesNewRomanPSMT
TimesNewRomanPS-BoldMT
TimesNewRomanPS-ItalicMT
(Times New Roman != TimesNewRomanPS and what's up with that MT?)
Other problem with it: No font face name contains Regular, but that is what users expect to see in the options (see the TextEdit screenshot).
HelveticaNeue (Without - Anything)= Regular.
MT = Monotype
See: http://www.fonts.com/support/faq/lt-mt-ef-abbreviations
How to use fonts that are not available on iOS as default?
You will need to config your PList
Drag the font files into your resource folder
Then you can use the new custom font like below code:-
[self.activateBtn.titleLabel setFont:
[UIFont fontWithName:#"ProximaNova-Regular" size:15]];
For more information, you may visit:
Use custom fonts in iPhone App

Resources