动态模拟 iOS 动态类型系统文本大小 (UIContentSizeCategory)

Dynamically Mocking iOS Dynamic Type System Text Size (UIContentSizeCategory)

我想使用不同的系统文本大小选项(包括辅助功能大小)轻松测试我的应用程序。这些可以在设置应用程序中设置(显示和亮度 => 文本大小或常规 => 辅助功能 => 较大的文本)。

目前我能找到的唯一方法是进入“设置”并使用 UI 更改值(编辑:,如下所述)。这很慢而且很麻烦。我怀疑有一种方法可以使用私有 APIs 动态地改变它,但我不知道如何做。由于我的目标是仅将其用于调试,私有 API 使用和调配都可以(此代码不会进入生产环境)。

为了尝试找到一个私有的 API 来执行此操作,我查看了一些逆向工程资源。我不熟悉反汇编程序、符号表、class 转储和查找我可以使用的私有 APIs,但这是我迄今为止尝试过的:

有关 IDA 结果的更多信息:

我真的不知道如何阅读反汇编,但 +[UIFont preferredFontForTextStyle:] 似乎指向一个名为 ___UIFontForTextStyle 的符号,它似乎指向一些名为 [=22] 的 interesting-sounding 符号=] 和 _getUIContentSizeCategoryPreferenceClass

我还使用 command-line 实用程序 nm on UIFoundation.framework. They were marked with the lowercase letter "s" meaning, apparently, "The symbol is in an uninitialized data section for small objects." 找到了这些符号。我不知道这意味着什么(我收集到的只是它们不是 class 或方法)。

在网络上搜索 _getUIContentSizeCategory... 符号没有任何结果,但附近有另一个符号 _getUIApplicationClass。我搜索了那个,因为它听起来有点笼统,并在一些 WebKit source 中找到了类似的东西。可能没什么,但也许这是 Apple 内部会议。无论如何,这个例子并不能真正帮助我解决问题。

无论如何,感谢您到目前为止的阅读。如果你还在这里,我的问题是:

我希望能够动态模拟动态类型大小首选项的值。这些反汇编符号可能会有所帮助,但也许我走错了路。感觉解决方案很接近,但我无法将所有部分放在一起。

将此值设置为启动参数很好,但不能完全解决我的问题。同样,在 plist 中修改 Simulator 的值对自动化也有好处,但不能解决我的问题。

有没有办法在运行时动态改变这个值?

好尴尬!我正在查看一些过时的 iOS 9.x 文档并错过了 UITraitCollection 在 iOS 10 中获得 init(preferredContentSizeCategory: UIContentSizeCategory)var preferredContentSizeCategory: UIContentSizeCategory,这Brandon Williams 很有帮助地向我指出。这完全满足了我的需求。

一种简单的方法是围绕 UIFontMetrics 编写包装器并通过它路由所有 UIContentSizeCategoryDidChange 通知。它允许 unit/UI 测试各种动态类型设置。 I wrote about it here.