问题
I have a stopwatch feature in my app that uses a centered attributed UILabel
with a proportionally spaced font to render time. At every time increment the width of the label changes, creating a bouncing effect that looks especially bad at fast speeds. Here is an example.
How can I fix this?
iOS 9 UPDATE
It is now a one-liner:
UIFont.monospacedDigitSystemFontOfSize(17, weight: UIFontWeightRegular)
Also, last time I tried, the solution below did not work for iOS 9. Wasted quite a bit of time debugging before stumbling on this in the header.
SOLUTION
Turned out to be trivial with Text Kit in iOS 7.
Make sure Core Text is imported:
#import <CoreText/CoreText.h>
Create a setting that converts proportional numbers into monospaced:
NSArray *monospacedSetting = @[@{UIFontFeatureTypeIdentifierKey: @(kNumberSpacingType),
UIFontFeatureSelectorIdentifierKey: @(kMonospacedNumbersSelector)}];
Create a new font descriptor by appending the current one used by UILabel
:
UIFontDescriptor *newDescriptor = [[timeLabel.font fontDescriptor] fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute: monospacedSetting}];
Update label's font:
// Size 0 to use previously set font size
timeLabel.font = [UIFont fontWithDescriptor:newDescriptor size:0];
回答1:
Use a monospaced font or pass parameters when creating the font which force monospaced numbers:
//kNumberSpacingType 6
//kMonospacedNumbersSelector 0
NSArray *setting = @[
@{
UIFontFeatureTypeIdentifierKey: @(6),
UIFontFeatureSelectorIdentifierKey: @(0)
}
];
return [UIFont fontWithDescriptor:[[self fontDescriptor] fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute : setting}] size:0.0];
回答2:
For future readers:
This is how to enable monospaced numbers on iOS 9 with San Francisco:
let originalFont = UIFont.systemFontOfSize(17)
let originalFontDescriptor = originalFont.fontDescriptor()
let fontDescriptorFeatureSettings = [
[
UIFontFeatureTypeIdentifierKey: kNumberSpacingType,
UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector
]
]
let fontDescriptorAttributes = [UIFontDescriptorFeatureSettingsAttribute: fontDescriptorFeatureSettings]
let fontDescriptor = originalFontDescriptor.fontDescriptorByAddingAttributes(fontDescriptorAttributes)
let font = UIFont(descriptor: fontDescriptor, size: 0)
Edit:
Also available on GitHub: https://github.com/salutis/swift-font-monospaced-digits
来源:https://stackoverflow.com/questions/21569861/how-to-stop-a-time-uilabel-from-resizing-at-every-time-increment