iOS Prevent timer UILabel 'shaking' when numbers change - ios

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

Related

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.

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.

UIFont - how to get system thin font

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)

Swift - iOS 8 - NSKernAttributeName character spacing problems

Part of my application facilitates the drawing of stored string values to a graphics context to be viewed by the user. This is being done with an attributed string with the below Attributes.
//adding the attributes to the NSAttributedString
let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as NSMutableParagraphStyle
let textColor = UIColor.blackColor()
let boxTextFontAttributes = [
NSFontAttributeName : font!,
NSForegroundColorAttributeName: textColor,
NSParagraphStyleAttributeName: textStyle,
NSKernAttributeName: (7.62),
]
I'm seeing a problem with the NSKernAttributeName character spacing on the output.
I have 2 Strings, both with the same CGRect dimensions (but different y-positions (one below the other)), both upper case, same font & size.
Whenever it comes to a 'thinner' character in one of the strings, such as an "I", it looks to impact the spacing of the following characters.
I basically need to have each character in both strings to be vertically in-line to the string above/below regardless of what character it is? I can only assume that even though it may have a set spacing between the characters, each character still has an individual 'width' of sorts that impacts the rest. Is there a way to standardise this?
Any help would be appreciated - (apologies for not being able to post a picture due to lack of reputation points)
A monospaced font corrected the issue of the character alignment. Some example monospaced fonts available in iOS 8 are Courier & Menlo. Useful post: What is a monospace font in iOS?

How to decrease the weight of UILabel text font?

I'm trying to reduce the weight of font in UILabel text.
I'm using Helvetica font, still i want the text more thinner.
how can i reduce the thickness of UILabel text font weight?
You can set the font to a different variant in the same family, for instance Helvetica-Light (where by default you get Helvetica-Regular). iosfonts.com provide a nice site for viewing font options.
You can't set an arbitrary weight for any font. Some fonts have a bold and regular variant. A smaller number also have a "light" variant. As the other poster said, if the font is one of those that has a light variant, you can select that, but you can't arbitrarily reduce the weight of a font.
You need to reduce the pointSize of the UIFont used by the UILabel:
UILabel *label; // Your Label
UIFont *font = label.font;
label.font = [font fontWithSize:(font.pointSize - 4)];
This example reduces the font by 4 points.

Resources