如何从 iOS 设置中检测动态字体大小更改?

Posted

技术标签:

【中文标题】如何从 iOS 设置中检测动态字体大小更改?【英文标题】:How to detect Dynamic Font size changes from iOS Settings? 【发布时间】:2013-09-27 21:10:01 【问题描述】:

在settings->general->text size里面,修改了文本大小后,我必须退出我自己的应用才能应用大小

 [UIFont preferredFontForTextStyle:..]

是否有委托或通知通知我的应用重新应用新尺寸?

更新:我尝试了以下但有趣的是,字体大小将在我 BG 并启动应用程序 TWICE 后应用。

- (void)viewDidLoad

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fromBg:) name:UIApplicationDidBecomeActiveNotification object:nil];




 -(void) fromBg:(NSNotification *)noti

    self.headline1.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
    self.subHeadline.font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
    self.body.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
    self.footnote.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
    self.caption1.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
    self.caption2.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2];
//    [self.view layoutIfNeeded];


【问题讨论】:

【参考方案1】:

您在UIContentSizeCategory 上收听大小更改通知。

Swift 3.0: NSNotification.Name.UIContentSizeCategoryDidChange

Swift 4.0 或更高版本: UIContentSizeCategory.didChangeNotification

【讨论】:

好的,但是我该怎么做才能应用新的字体大小?我是否再次将字体设置为preferredFontForTextStyle? @mskw 是的,这就是你需要做的所有事情。 在 Swift 4.2 中出现问题,adjustsFontForContentSizeCategory 无法正常工作,通知始终有效。【参考方案2】:

使用 Swift 5 和 ios 12,您可以选择以下三个解决方案之一来解决您的问题。


#1。使用UIContentSizeCategoryAdjustingadjustsFontForContentSizeCategory 属性

UILabelUITextFieldUITextView 符合 UIContentSizeCategoryAdjusting 协议,因此有一个名为 adjustsFontForContentSizeCategory 的实例属性。 adjustsFontForContentSizeCategory 有以下声明:

一个布尔值,指示对象是否在设备的内容大小类别发生变化时自动更新其字体。

var adjustsFontForContentSizeCategory: Bool  get set 

下面的UIViewController 实现展示了如何使用adjustsFontForContentSizeCategory 检测iOS 设置中的动态字体大小变化并做出反应:

import UIKit

class 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。使用UIContentSizeCategorydidChangeNotification 类型属性

UIContentSizeCategory 有一个名为didChangeNotification 的类型属性。 didChangeNotification 有以下声明:

在用户更改首选内容大小设置时发布。

static let didChangeNotification: NSNotification.Name

preferredContentSizeCategory 属性中的值更改时发送此通知。通知的 userInfo 字典包含 newValueUserInfoKey 键,它反映了新设置。

下面的UIViewController 实现展示了如何使用didChangeNotification 检测iOS 设置中的动态字体大小变化并做出反应:

import UIKit

class 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。使用UITraitCollectionpreferredContentSizeCategory 属性

UITraitCollection 有一个名为preferredContentSizeCategory 的属性。 preferredContentSizeCategory 有以下声明:

用户喜欢的字体大小选项。

var preferredContentSizeCategory: UIContentSizeCategory  get 

使用动态类型,用户可以要求应用使用大于或小于系统定义的正常字体大小的字体显示文本。例如,有视觉障碍的用户可能会要求更大的默认字体大小,以便更容易阅读文本。使用此属性的值来请求与用户请求的大小相匹配的UIFont 对象。

下面的UIViewController 实现展示了如何使用preferredContentSizeCategory 检测iOS 设置中的动态字体大小变化并做出反应:

import UIKit

class 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 */
        
    



来源:

useyourloaf.com / Auto Adjusting Fonts for Dynamic Type

【讨论】:

感谢您的详细解答!我找不到是否有办法以编程方式检测较大的可访问性大小开关是否打开或关闭。不知道能不能实现? @Dave 你可以这样测试它:if traitCollection.preferredContentSizeCategory.isAccessibilityCategory /* ... */ 。有关详细信息,请参阅useyourloaf.com / Making Space For Dynamic Type。 我们如何从覆盖方法之外访问特征集合?

以上是关于如何从 iOS 设置中检测动态字体大小更改?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 11 中 UINavigationBar 大标题的默认字体?

如何在 iOS 中增加 NSAttributedstring 的字体大小

如何使用 CSS 媒体查询检测 Android 设备的默认字体大小?

如何在iOS7中使用具有动态文本大小的自定义字体

如何在 reactjs 中动态更改字体大小和字体粗细?

iOS 动态类型 - 设置最小字体大小