I want to embrace dynamic type in my app, and I want it to be responsive to text size changes while it's running, without restarting the app (when I restart, it applies the new size successfully).
I've implemented UIContentSizeCategoryDidChangeNotification
in my app delegate, and fired a notification on applicationDidBecomeActive:
, notifying my view controllers. In my view controller's handler method, I've tried:
[self.view setNeedsDisplay];
[self.view setNeedsLayout];
[self.view invalidateIntrinsicContentSize];
But none seem to work. It does nothing. It is called (hits the breakpoint) when app becomes active, and it does get called for the frontmost view, but nothing changes.
How can I make my app respond to type changes dynamically when running?
First, your UIViewController
s need to observe the UIContentSizeCategoryDidChangeNotification
notification (which you are). As documentation, I'll leave an example:
- (void)viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentSizeCategoryDidChangeNotification:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
}
Next, we'll define our selector, contentSizeCategoryDidChangeNotification:
. This function is where we need to explicitly update each UI element (for UILabel
, UIButton
, etc.). Simply triggering a layout pass will not do this.
For example, say you have a label and button:
- (void)contentSizeCategoryDidChangeNotification {
// Updating a UILabel's size for a given text style:
self.headlineLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
// Similarly, updating a UIButton's size for a given style:
[self.button.titleLabel setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]];
...
}
+ (UIFont)preferredFontForTextStyle:
will return the correctly sized UIFont
for a given text style, adjusted for the system Dynamic Type content size (which range from XS
to XXXL
).
Finally, remember to remove yourself as an observer:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Hope this helps!
In iOS 10+, the adjustsFontForContentSizeCategory
now exists. Set this to YES on your Labels and it will auto-update the font size, assuming your font is set to use Text Style
font.
You can also set this from IB with the "Automatically Adjusts Font" checkbox. Note that this checkbox has no impact if it is not paired with a Text Style
font (such as Body
, Headline
, Subhead
, etc.).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With