Skip to content

Latest commit

 

History

History
169 lines (119 loc) · 7.63 KB

README.md

File metadata and controls

169 lines (119 loc) · 7.63 KB

SSDynamicText

iOS 11 fully covers SSDynamicText functionality. Library won't be supported anymore.


Circle CI codecov.io Version Carthage compatible

iOS 7's UIFontDescriptor is pretty neat. Also pretty neat is dynamic text that responds to the preferred text size that the user specified in Settings.app.

What's not so neat, though, is that +[UIFont preferredFontForTextStyle:] only works with the system font, Helvetica Neue (iOS 8) or San Francisco (iOS 9). What if you have custom fonts and want to respect the user's text size preference?

SSDynamicText is a collection of simple UILabel, UIButton, UITextField, and UITextView subclasses inspired by this SO answer.

iOS 10 added to UILabel, UITextField and UITextView built-in dynamic font size support via adjustsFontForContentSizeCategory, so there's no need to manually update font after content size category change. Sadly accessibility content size categories work only for .body style.

But finally in iOS 11 Apple introduced UIFontMetrics which allows to use custom fonts with all content size categories support. It's supported by UILabel (so UIButton as well), UITextField and UITextView. Works for plain text and NSAttributedString.

// Plain text
UIFont *font = [UIFont fontWithName:@"Courier" size:28.0f];
label.font = [UIFontMetrics.defaultMetrics scaledFontForFont:font];
label.adjustsFontForContentSizeCategory = YES;
label.text = @"Plan text";

// Attributed text
UIFont *biggerFont = [UIFont fontWithName:@"Courier" size:28.0f];
UIFont *scaledBiggerFont = [[UIFontMetrics metricsForTextStyle:UIFontTextStyleTitle1] scaledFontForFont:biggerFont];
UIFont *smallerFont = [UIFont fontWithName:@"Courier" size:13.0f];
UIFont *scaledSmallerFont = [[UIFontMetrics metricsForTextStyle: UIFontTextStyleFootnote] scaledFontForFont:smallerFont];

NSAttributedString *biggerAttributedText = [[NSAttributedString alloc] initWithString:@"Bigger text"
                                                                           attributes:@{ NSAccessibilityFontTextAttribute : scaledBiggerFont }];
NSAttributedString *smallerAttributedText = [[NSAttributedString alloc initWithString:@"smaller text"
                                                                           attributes:@{ NSAccessibilityFontTextAttribute : scaledSmallerFont }];

NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
[attributedText appendAttributedString:biggerAttributedText];
[attributedText appendAttributedString:smallerAttributedText];

label.adjustsFontForContentSizeCategory = YES;
label.attributedText = attributedText;
// Plain text
let font = UIFont(name: "Courier", size: 17.0)!
label.font = UIFontMetrics.default.scaledFont(for: font)
label.adjustsFontForContentSizeCategory = true
label.text = "Plan text"

// Attributed text
let biggerFont = UIFont(name: "Courier", size: 28.0)!
let scaledBiggerFont = UIFontMetrics(forTextStyle: .title1).scaledFont(for: biggerFont)
let smallerFont = UIFont(name: "Courier", size: 13.0)!
let scaledSmallerFont = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: smallerFont)

let biggerAttributedText = NSAttributedString(string: "Bigger text",
                                              attributes: [.font: scaledBiggerFont])
let smallerAttributedText = NSAttributedString(string: "smaller text",
                                               attributes: [.font: scaledSmallerFont])

let attributedText = NSMutableAttributedString()
attributedText.append(biggerAttributedText)
attributedText.append(smallerAttributedText)

label.adjustsFontForContentSizeCategory = true
label.attributedText = attributedText

Requirements

Xcode 7.0+ with iOS 7.0+ SDK.

Install

Add to your Podfile:

pod 'SSDynamicText', '~> 1.0.0'

Add to your Cartfile:

github "splinesoft/SSDynamicText", ~> 1.1.0

Example usage

SSDynamicText provides dynamic auto-sizing labels, buttons, text fields, and text views that respond when the user changes her preferred text size. Check out a full example.

UIKit views that responds when the user changes her preferred text size:

SSDynamicLabel

SSDynamicLabel *myLabel = [SSDynamicLabel labelWithFont:@"Courier"
                                               baseSize:16.0f];
myLabel.text = @"Auto-sizing text!";

// Already have a font descriptor?
UIFontDescriptor *aDescriptor = [UIFontDescriptor fontDescriptorWithName:@"Courier"
                                                                    size:16.0f];
SSDynamicLabel *otherLabel = [SSDynamicLabel labelWithFontDescriptor:aDescriptor];

SSDynamicButton

SSDynamicButton *myButton = [SSDynamicButton buttonWithFont:@"Courier"
                                                   baseSize:16.0f];
[myButton setText:@"Auto-sizing text!" forControlState:UIControlStateNormal];

SSDynamicTextField

SSDynamicTextField *myTextField = [SSDynamicTextField textFieldWithFont:@"Courier"
                                                               baseSize:16.0f];
myTextField.text = @"Auto-sizing text!";

SSDynamicTextView

SSDynamicTextView *myTextView = [SSDynamicTextView textViewWithFont:@"Courier"
                                                           baseSize:16.0f];
myTextView.text = @"Auto-sizing text!";

UIFont+SSTextSize

Create a UIFont object using the specified font name and base size. The actual size of the returned font is adjusted by the user's current preferred font size (specified in Settings.app).

UIFont *myFont = [UIFont dynamicFontWithName:@"Courier" baseSize:16.0f];

UIApplication+SSTextSize

This property returns a numeric delta between the default size setting (Large) and the user's current preferred text size.

You probably don't need to use this directly.

NSInteger textDelta = [[UIApplication sharedApplication] preferredFontSizeDelta];

NSAttributedString Support

SSDynamicText supports attributed text! Assign your NSAttributedString to the new dynamicAttributedText property.

UITextView and UITextField sometimes internally call -setAttributedText: even with normal text. To best accommodate that internal implementation detail, we've added a new dynamicAttribtuedText property instead of overriding -setAttributedText:.

@property (nonatomic, copy) NSAttributedString *dynamicAttributedText;

Thanks!

SSDynamicText is a @jhersh production -- (electronic mail | @jhersh)