Добро пожаловать в разбор кейсов, как Apple использует элементы UIKit
в своих приложениях. Сегодня разберу Календарь. До этого уже разобрал Калькулятор. Я - Иван Воробей, веду телеграмм канал для iOS Разработчиков «Код Воробья».
Календарь сделали на сценах. Для iPhone root-сцена называется MobileCalWindow
.
Экран дня
Контейнер UINavigationController
. Навигацию между страницами-днями сделали на UIScrollView
, класс назвали BlockableScrollView
. У скрола включен пейджинг.
В памяти хранят вчерашений, сегодняшний и завтрашний день. В Календаре используют кастомную систему переиспользования, что-то похожее на UICollectionView
, но управляется вручную. Скорее всего, это сделано для оптимизации в прошлом и до нашего времени сохранился легаси-код.
Ячейки событий сделали двухслойными картинками. Первый слой - фоновая картинка, второй слой - текст внутри события. Залитая линия справа события это часть фоновой картинки. У события две точки для изменения времени - слева внизу и справа вверху. Им расширили размеры, но фон - прозрачный. Лейаут ячеек на констрейнтах.
UINavigationBar
базовый, справа добавили Stack View для кнопок. Панель с датами назвали PaletteView
. Это UIScrollView
и она не является частью UINavigationBar
. Всю панель поместили над контентом, но под баром и присоединили к нижней точке бара. Фон повторили, чтобы скрыть переход.
![](https://habrastorage.org/getpro/habr/upload_files/235/015/ed5/235015ed54d493bfa2372cd873399fe6.png)
Разметка времени слева сделана на одном слое, текст отрисовали внутри CALayer
. Время разместили слева экрана, события сместились вправо.
![](https://habrastorage.org/getpro/habr/upload_files/f4f/08c/93e/f4f08c93e8472ff265e3bdb594346752.png)
Разметка времени лежит внутри UIVisualEffectView
, но визуально применений не нашёл.
Как писал выше, событие - это картинка. Чтобы обрабатывать нажатие на картинку, нужно добавить UITapGestureRecognizer
. Так инженеры эпл и сделали - для вью каждого дня добавили тап-жест. В вот жест драга добавлен один на весь экран, а не отдельные жесты для каждого события.
Новое событие
Экран презентуется как модальный контроллер. Сделан на UITableViewController
, вью таблицы назвали EKCalendarItemEditorTableView
.
![](https://habrastorage.org/getpro/habr/upload_files/c20/fad/6d7/c20fad6d724e03a1e52f538b6c48936b.png)
Ячейки назвали EKUITableViewCell
. Disclosure Indicator справа тоже системные. Ничего уникального в экране не нашёл.
Экран по месяцам
Главная вью UIScrollView
. При переходе на экран по месяцам, панель с числами PaletteView
съезжает вверх. Она остается в памяти, но не видна на экране телефона.
А вот панель с днями недели визуально остается на месте, но на самом деле это копия. Оригинальная панель уезжает наверх вместе с PaletteView
.
![](https://habrastorage.org/getpro/habr/upload_files/186/a15/a13/186a15a13e8e11135a09376d93a0f571.png)
Названия месяцев сделаны на UILabel
. Месяц разбивается на горизонтальные недели. Контейнер назвали CompactMonthWeekView
.
![](https://habrastorage.org/getpro/habr/upload_files/dc2/fda/29c/dc2fda29c409b238fb93081ea08c54be.png)
Внутри дни недели сделаны через CALayer
. Только для текущего дня, который красный кружок, дата это UILabel
с красным фоном. Назвали CompactMonthWeekTodayCircle
. Лейаут на фреймах.
Сепаратор между неделями это UIView
с фоном и высотой 0.333
.
Превью дня
Всплывающая панель это таблица. Ячейки назвали EKUIOccurrenceTableViewCell
. Лейаут на констрейнтах. Практически все расстояния между элементами выставили фиксированным значением. Отступ от краев ячейки тоже.
![](https://habrastorage.org/getpro/habr/upload_files/533/a0c/5db/533a0c5dba9149770a358a3dc000b6b2.png)
Контент ячеек сделан на UILabel
. Цветная полоска слева это UIView
с фоном.
Экран Год
Надписи годов сделали через UILabel
. Контейнер для хедера назвали CompactYearViewYearHeader
. Месяцы группируются по 3 в линию. Даты внутри месяца и название отрисовали слоем внутри вью, назвали CompactYearMonthView
.
![](https://habrastorage.org/getpro/habr/upload_files/10b/4ed/973/10b4ed973daf75794927fe57d0c336d5.png)
Сделано на UIScrollView
с кастомной системой переиспользования.
Список календарей
Сделали таблицей. Ячейки называются EKCalendarChooserCell
. Круглые чекмарки слева сделали картинками. Нативный экран без кастомизации.
![](https://habrastorage.org/getpro/habr/upload_files/ebe/8b9/cad/ebe8b9cad6fac6db1cf556e533ae663c.png)
Accessibility
Все интерактивные элементы поддерживают Voice Over
и Voice Control
. Расставлены подсказки.
![](https://habrastorage.org/getpro/habr/upload_files/ce2/9d2/9c7/ce29d29c729278c03eda2f5979c56e93.png)
Управление голосом размечено на каждый час в течение дня. Для событий диктуется заголовок, время, календарь и как можно взаимодействовать с элементом.
На экране года Voice Control
только для месяцев. Voice Over
для года и названия месяцев.
![](https://habrastorage.org/getpro/habr/upload_files/80a/d1b/847/80ad1b847d89f22052bcc8b292853e7d.png)
Accessibility
добавлен по всему приложению.