Динамический Mocking iOS Динамический тип Размер текста системы (UIContentSizeCategory)
Я бы хотел легко проверить свое приложение с различными вариантами размера системного текста, включая размеры доступности. Их можно установить в приложении "Настройки" ( "Экран" и "Яркость" > "Размер текста" или "Общий" > "Доступность" > "Большой текст" ).
Единственный способ, который я могу найти в настоящее время, - это перейти в Настройки и изменить значение с помощью пользовательского интерфейса (edit: частичное решение, описанного ниже). Это медленный и громоздкий. Я подозреваю, что есть способ динамически изменить его с помощью частных API, но я не могу понять, как это сделать. Поскольку моя цель состоит в том, чтобы использовать это только для отладки, использование частного API и swizzling прекрасное (этот код не будет работать).
Чтобы попытаться найти частный API для этого, я посмотрел на некоторые обратные инженерные ресурсы. Я новичок в дизассемблерах, таблицах символов, дампах классов и поиске частных API, которые я могу использовать, но это то, что я пробовал до сих пор:
-
Я успешно swizzled -[UIApplication preferredContentSizeCategory]
(другие сообщения говорили, что это сработало в прошлом), но это не влияет на результат, возвращаемый с +[UIFont preferredFontForTextStyle:]
.
-
Использование дизассемблера IDA Я обнаружил, что +[UIFont preferredFontForTextStyle:]
находится в частной структуре UIFoundation.framework
. (-[UIApplication preferredContentSizeCategory]
находится в UIKit.framework
, но разборка не выглядела бесполезной).
-
Так же, как я начал писать этот вопрос (так всегда бывает), я обнаружил частичное решение . Можно задать параметр запуска в схеме, чтобы установить значение при запуске. Это полезно, но не то, что мне нужно.
-
В приведенном выше ответе я нашел значение для предпочтения пользователя, по-видимому, хранится в "файле com.apple.UIKit.plist
, расположенном в каталоге Simulator data/Library/Preferences
". Значение, которое мы получаем, можно установить из утилиты командной строки plutil
. Это тоже улучшение! Но я бы хотел динамически изменить его во время выполнения.
Подробнее о моих результатах от IDA:
Я действительно не знаю, как читать разборку, но +[UIFont preferredFontForTextStyle:]
, кажется, указывает на символ с именем ___UIFontForTextStyle
, который, как представляется, указывает на некоторые интересные звуковые символы, называемые _getUIContentSizeCategoryUnspecified
и _getUIContentSizeCategoryPreferenceClass
![Разборка для <code> ___ UIFontForTextStyle </code>]()
Я также нашел эти символы, используя утилиту командной строки nm
в UIFoundation.framework
. Они были отмечены строчной буквой "s", что означает, по-видимому, "Символ находится в неинициализированной секции данных для небольших объектов" .. Я понятия не имею, что это значит (все, что я собрал, это то, что они не являются классом или методом).
Поиск в Интернете для символов _getUIContentSizeCategory...
ничего не дает, но рядом с ним есть еще один символ _getUIApplicationClass
. Я искал это, так как это звучало немного более общее, и нашел нечто похожее в некотором источнике WebKit. Не может быть ничего, но, возможно, это внутреннее соглашение Apple. Несмотря на это, этот пример не помогает мне решить проблему.
В любом случае спасибо за чтение до сих пор. Если вы все еще здесь, мой вопрос:
Я хотел бы иметь возможность динамически оценивать значение для предпочтения размера динамического типа. Эти символы разборки могут помочь, но, возможно, я ошибаюсь. Похоже, что решение близко, но я просто не могу собрать все части.
Установка этого значения в качестве аргумента запуска хороша, но не полностью решает мою проблему. Аналогично, изменение значения Simulator в plist
также хорошо для автоматизации, но не решает мою проблему.
Есть ли способ динамически изменять это значение во время выполнения?
Ответы
Ответ 1
Как смущающе! Я смотрел какую-то устаревшую документацию iOS 9.x и пропустил этот UITraitCollection
полученный init(preferredContentSizeCategory: UIContentSizeCategory)
и var preferredContentSizeCategory: UIContentSizeCategory
в iOS 10, который мне был полезен Брэндон Уильямс. Это прекрасно удовлетворяет мои потребности.
Ответ 2
Один простой способ - написать обертку вокруг UIFontMetrics
и UIContentSizeCategoryDidChange
через UIContentSizeCategoryDidChange
все уведомления UIContentSizeCategoryDidChange
. Это позволяет для модульного/пользовательского интерфейса тестировать различные настройки динамического типа. Я написал об этом здесь.