Представь, что ты незрячий. Вот так ты услышишь эту картинку: «Буква D в чёрных очках и с белой палочкой и буква O в инвалидной коляске смотрят на большой телефон. На экране телефона скриншот приложения Додо Пиццы, который проговаривает названия ячейки меню из пицц для VoiceOver. Картинка стилизована под старые компьютеры и выполнена в зелёных цветах. Нажать кнопку «Читать дальше».  Телефон давно стал продолжением меня, и я слабо представляю свою жизнь без пары десятков приложений, которыми пользуюсь каждый день. Но как быть тем, кто не может взять телефон в руку или посмотреть на экран? Фичи iOS открывают людям с ограничениями в движении, зрении и слухе эти возможности в обычной жизни. С их помощью можно увеличить размер текста и контраст, сделать моно-аудио, убрать анимации. Можно работать с интерфейсом без экрана — на слух (для незрячих) или вообще управлять только голосом (если человек ограничен в движении).  Адаптировать можно любое приложение и даже некоторые игры. Сегодня я расскажу как iOS-разработчикам сделать первые шаги в этом направлении.  Начиная с iOS 13 телефон можно контролировать голосом. Voice Control упрощает жизнь и даёт новый уровень свободы людям с ограничениями в движении. Посмотрите видео, в нём Apple показывает, как именно это работает:  Ещё более детально об управлении телефоном можно узнать вот в этих видео: Включив эту функцию, вы сможете отдавать команды телефону. Увы, пока работает только с английским языком. Например, говоришь «tap purchase», — и кнопка купить нажимается. Для управления кнопками с иконками (без названий в виде слов) можно скомандовать «show numbers», и у всех кнопок появятся цифровые подписи. Теперь можно сказать «tap five» и пятая кнопка нажмётся. Для работы со сложными элементами (карты, графики), можно попросить телефон показать сетку, тогда место на карте можно будет выбирать по номеру ячейки.  Доступных жестов очень много. Полное описание всех вы можете посмотреть в настройках телефона: Settings → Accessibility → Voice Control → Customize Commands.  Чтобы вашим приложением могли пользоваться незрячие люди, его нужно адаптировать с помощью VoiceOver. Несколько отличий от обычного использования: Полный список доступных жестов. Voice Control и VoiceOver работают на одной технологии, поэтому адаптировав одно, мы получаем поддержку второго.  Для начала нужно побыть пользователем: включить, попробовать поюзать самостоятельно и настроить шорткат (быстрое включение), чтобы легко было проверять новые фичи.  Где включить: включать/отключать можно через Siri или через настройки (Settings → Accessibility → VoiceOver).  Как настроить шорткат: для быстрого доступа включите шорткат на тройное нажатие кнопки «домой» (или «выключить» для X моделей): Settings → Accessibility → Accessibility Shortcut → Поставить галочку рядом с VoiceOver.  Основа доступности — протокол UIAccessibilityElement. Для улучшения работы VoiceOver нужно: Что-то можно настроить в Interface builder, но часть настроек доступна только в коде.  Каждой кнопке надо дать короткое звучное название. VoiceOver подстрахует, если вы забыли — попытается прочитать текст или название иконки на кнопке, но часто получается так себе.  Что нужно подписывать: Дополнительно к названию можно написать значение. Например, у слайдера будет название «яркость», а значение — «50%». У кнопки «Добавить в корзину» стоит указать количество или итоговую цену, чтобы подытожить действие всего экрана и не купить лишнего.  Если вы хотите дополнительно пояснить действие, то можно записать подсказку в .accessibilityHint. Но сильно полагайтесь на подсказки не стоит: постоянные пояснения надоедают, поэтому некоторые пользователи отключают их через настройки телефона. По умолчанию проговаривается каждый контрол по отдельности. Это неудобно: зоны нажатий уменьшаются, можно что-то не заметить и т.д. Нужно обобщать. Например, в меню ячейка состоит из картинки, названия, описания и кнопки с ценой. Такая детальность не нужна: маленькую картинку можно скрыть, название и цену прописать в заголовок ячейки, а состав в её значение. Ячейка станет одним целым, а меню превратится в нормальный набор продуктов. Этих знаний достаточно, чтобы начать улучшать собственную программу. Разберём на примере меню с пиццами.  Неадаптированная версия для незрячего выглядит так:  Несколько очевидных проблем, которые предстоит решить: 24 в правом верхнем углу — это количество додо-рублей.
Так и надо подписать: Этот код можно разместить в любом месте, где у вас есть актуальное значение для value. Для кнопки города можно сделать нечто похожее: лейбл — ваш город, значение — Москва. Но можно и не делать, вроде и так понятно. Не переусердствовать — тоже важная задача.  Акции вверху — это горизонтальный UICollectionView. Внутри ячейки есть лейбл, именно его находит VoiceOver. Как поправить: Настроить можно в методе cellForItemAt: У ячейки с продуктом две проблемы: много элементов и неправильное описание цены.  Сейчас у ячейки несколько полей: название, описание, цена и картинка, 4 контрола на ячейку. Если в меню 10 продуктов, то это уже 40 маленьких контролов. Надо обобщить, чтобы было 10 продуктов, так получается ближе к смыслу.   Можно упростить:   Метод внутри ячейки, подставляет нужные значения: Группировать можно не только ячейки, но и все связанные смыслом контролы. Например, переключатель количества и цену стоит обрабатывать вместе: изменили количество — сказали новую цену. Тогда вместо четырёх глупых контролов появится один нормальный.  Для правильного написания «рублей» мы генерируем правильную строку и ставим её в accessibilityLabel для кнопки.  Просклонять нужно в файле Localizable.stringsDict:  Для навигации есть два вспомогательных жеста: скрабл и меджик тап. Скрабл возвращает на предыдущий экран. Чтобы его выполнить, проведите по экрану двумя пальцами, будто пишите букву Z. Ещё скраблом можно заканчивать ввод текста.  Меджик тап вызывает главную функцию текущего экрана. Нужно тапнуть дважды двумя пальцами. Можно включить песню в плеере или ответить на звонок. У меджик тапа есть UX-проблема — неочевидно, что он делает. Для себя мы решили так: если скрабл переходит на экран назад, то пусть меджик тап переводит на следующий экран по сценарию. На карточке пиццы это добавит её в корзину, если вы были в корзине, то перейдёте на экран доставки, а с доставки переключитесь на оплату.  Но если действие неочевидно, то можно рассказать о меджик тапе в подсказке у кнопки. Но помните: подсказки могут не проговариваться, зависит от настроек.  Если нажать на акцию или кнопку додо-рублей, откроется модальный экран. Если бы мы использовали UINavigationController, то ничего делать было бы не нужно. Но для модальных экранов нужно описать, как они реагируют на дополнительные жесты.   После того, как пользователь нарисует Z, вызовется метод accessibilityPerformEscape у firstResponder. Обычно, это текущий UIViewController. Вам достаточно реализовать этот метод, закрыть в нём экран и вернуть true, показав, что жест обработан и можно не проходить responder chain дальше: Похожим образом можно реагировать на меджик тап. Например, применить акцию из карточки: Проблемы адаптации находить несложно, стоит только включить VoiceOver, как на вас посыпятся десятки. Но спустя время находить новые проблемы станет сложнее, при этом легко пропустить что-то важное, ведь проблемы приходится находить на слух. Есть пара способов упростить жизнь разработчику.  Мы адаптировали один экран. Программировать нужно совсем немного, поддерживать доступность на базовом уровне легко.  Но за кадром осталось многое: разные accessibilityTraits, набор текста, навигация в приложении, custom actions, порядок фокусировки, accessibility notifications, ротор и клавиатуру Брайля. Об этом в следующий раз.  Если уже сейчас хотите узнать больше, то можно почитать: Чтобы не пропустить следующую статью, подписывайтесь на канал Dodo Pizza Mobile. Head of Mobile at Dodo Engineering