Хабрахабр

iOS 13 под лупой

Dynamic Type – хорошо, но работает не всегда. Сейчас я расскажу, как увеличиваются маленькие контролы в iOS 13 бесплатно, без регистрации и смс.

В прошлой статье мы натянули дайнамик тайп на меню iOS-приложения Dodo Pizza. Получилось неплохо. Но таббар под меню как был маленький, так им и остался – он не видоизменяется в зависимости от настройки размера текста.

Эта фича ещё не дошла до релиза, за что мне стыд и позор

Вы что, не заботитесь о людях с плохим зрением?
– Спокуха! – Но как же так, Dodo?

Немного о встроенном режиме «Лупа»

Системный таббар показывает превьюху каждого таба по лонг-тапу. Попробуйте включить «доступный» размер текста, а потом долго жать на любой таб в системном таббаре (например, в Музыке или в Фото). На экране появится вот такая вот всплывайка:

Помимо таббара режим «лупы» поддерживается кнопками в навбарах и тулбарах:

Полями поиска:

И ещё некоторыми контролами.

И, начиная с iOS 13, мы можем легко добавить такое же поведение своим контролам.

Как прикрутить UILargeContentViewerItem к приложению

К сожалению, этот протокол довольно скудно описан в документации, но это не беда, потому что его API выглядит довольно просто:

@available(iOS 13.0, *)
public protocol UILargeContentViewerItem : NSObjectProtocol var largeContentTitle: String? { get } var largeContentImage: UIImage? { get } var scalesLargeContentImage: Bool { get } var largeContentImageInsets: UIEdgeInsets { get }
}

Достаточно реализовать несколько из этих методов, названия которых говорят сами за себя, и ваш контрол будет показывать большую превьюху по лонг-тапу.

Очень простая реализация

Давайте навернём этот протокол на какую-нибудь кнопку в приложении. Например, на кнопку i в карточке продукта:

Добавляем 3 строчки кода:

nutritionButton.showsLargeContentViewer = true
nutritionButton.addInteraction(UILargeContentViewerInteraction())
nutritionButton.largeContentTitle = nutritionButton.accessibilityValue

Готово. Круто, да?

Будет лучше, если она будет не двухцветная, а одноцветная с вырезанной формой буквы i. Только вот чёт иконка, которая подтягивается по дефолту, мне не нравится. Такая как раз используется для .highlighted-стейта кнопки.

nutritionButton.largeContentImage = nutritionButton.image(for: .highlighted)

Норм.

А теперь завернём в экстеншн:

extension UIView { public func enableLargeContent(title: String? = nil, image: UIImage? = nil, scales: Bool = true, insets: UIEdgeInsets = .zero) { guard !showsLargeContentViewer else { return } showsLargeContentViewer = true addInteraction(UILargeContentViewerInteraction()) largeContentTitle = title largeContentImage = image scalesLargeContentImage = scales largeContentImageInsets = insets }
}

nutritionButton.enableLargeContent(title: nutritionButton.accessibilityValue, image: nutritionButton.image(for: .highlighted))

На самом деле многие стандартные иос-контролы уже реализуют часть методов этого протокола. А этот режим выключен, потому что надо стараться по-настоященскому увеличивать контент, а не прятать всё за лупой.

Перефразирую: используйте эту фичу только в крайнем случае, когда ну совсем никак не можете увеличить контрол.

Документация на всё это дело доступна в икскоде, если открыть интерфейс UILargeContentViewerItem.

Демо-проект в моём репо на GitHub

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть