How to detect Dynamic Font size changes from iOS Settings? How to detect Dynamic Font size changes from iOS Settings? ios ios

How to detect Dynamic Font size changes from iOS Settings?


You listen for the Size Change Notification on UIContentSizeCategory.

Swift 3.0:NSNotification.Name.UIContentSizeCategoryDidChange

Swift 4.0 or later:UIContentSizeCategory.didChangeNotification


With Swift 5 and iOS 12, you can choose one of the three following solutions in order to solve your problem.


#1. Using UIContentSizeCategoryAdjusting's adjustsFontForContentSizeCategory property

UILabel, UITextField and UITextView conform to UIContentSizeCategoryAdjusting protocol and therefore have an instance property called adjustsFontForContentSizeCategory. adjustsFontForContentSizeCategory has the following declaration:

A Boolean value indicating whether the object automatically updates its font when the device's content size category changes.

var adjustsFontForContentSizeCategory: Bool { get set }

The UIViewController implementation below shows how to detect and react to dynamic font size changes in iOS settings with adjustsFontForContentSizeCategory:

import UIKitclass ViewController: UIViewController {    let label = UILabel()    override func viewDidLoad() {        super.viewDidLoad()        label.text = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."        label.numberOfLines = 0        label.font = .preferredFont(forTextStyle: UIFont.TextStyle.body)        label.adjustsFontForContentSizeCategory = true        view.addSubview(label)        // Auto layout        label.translatesAutoresizingMaskIntoConstraints = false        let horizontalConstraint = label.centerXAnchor.constraint(equalTo: view.centerXAnchor)        let verticalConstraint = label.centerYAnchor.constraint(equalTo: view.centerYAnchor)        let widthConstraint = label.widthAnchor.constraint(equalToConstant: 300)        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint])    }}

#2. Using UIContentSizeCategory's didChangeNotification type property

UIContentSizeCategory has a type property called didChangeNotification. didChangeNotification has the following declaration:

Posted when the user changes the preferred content size setting.

static let didChangeNotification: NSNotification.Name

This notification is sent when the value in the preferredContentSizeCategory property changes. The userInfo dictionary of the notification contains the newValueUserInfoKey key, which reflects the new setting.

The UIViewController implementation below shows how to detect and react to dynamic font size changes in iOS settings with didChangeNotification:

import UIKitclass ViewController: UIViewController {    let label = UILabel()    override func viewDidLoad() {        super.viewDidLoad()        label.text = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."        label.numberOfLines = 0        label.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)        view.addSubview(label)        // Register for `UIContentSizeCategory.didChangeNotification`        NotificationCenter.default.addObserver(self, selector: #selector(preferredContentSizeChanged(_:)), name: UIContentSizeCategory.didChangeNotification, object: nil)        // Auto layout        label.translatesAutoresizingMaskIntoConstraints = false        let horizontalConstraint = label.centerXAnchor.constraint(equalTo: view.centerXAnchor)        let verticalConstraint = label.centerYAnchor.constraint(equalTo: view.centerYAnchor)        let widthConstraint = label.widthAnchor.constraint(equalToConstant: 300)        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint])    }    @objc func preferredContentSizeChanged(_ notification: Notification) {        label.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)        /* perform other operations if necessary */    }}

#3. Using UITraitCollection's preferredContentSizeCategory property

UITraitCollection has a property called preferredContentSizeCategory. preferredContentSizeCategory has the following declaration:

The font sizing option preferred by the user.

var preferredContentSizeCategory: UIContentSizeCategory { get }

With Dynamic Type, users can ask that apps display text using fonts that are larger or smaller than the normal font size defined by the system. For example, a user with a visual impairment might request a larger default font size to make it easier to read text. Use the value of this property to request a UIFont object that matches the user's requested size.

The UIViewController implementation below shows how to detect and react to dynamic font size changes in iOS settings with preferredContentSizeCategory:

import UIKitclass ViewController: UIViewController {    let label = UILabel()    override func viewDidLoad() {        super.viewDidLoad()        label.text = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."        label.numberOfLines = 0        label.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)        view.addSubview(label)        // Auto layout        label.translatesAutoresizingMaskIntoConstraints = false        let horizontalConstraint = label.centerXAnchor.constraint(equalTo: view.centerXAnchor)        let verticalConstraint = label.centerYAnchor.constraint(equalTo: view.centerYAnchor)        let widthConstraint = label.widthAnchor.constraint(equalToConstant: 300)        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint])    }    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {        super.traitCollectionDidChange(previousTraitCollection)        if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory {            self.label.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)            /* perform other operations if necessary */        }    }}

Sources: