Добро пожаловать в разбор кейсов, как Apple использует элементы UIKit в своих приложениях. Сегодня разберу Календарь. До этого уже разобрал Калькулятор. Я - Иван Воробей, веду телеграмм канал для iOS Разработчиков «Код Воробья».  Календарь сделали на сценах. Для iPhone root-сцена называется MobileCalWindow. Контейнер UINavigationController. Навигацию между страницами-днями сделали на UIScrollView, класс назвали BlockableScrollView. У скрола включен пейджинг. В памяти хранят вчерашений, сегодняшний и завтрашний день. В Календаре используют кастомную систему переиспользования, что-то похожее на UICollectionView, но управляется вручную. Скорее всего, это сделано для оптимизации в прошлом и до нашего времени сохранился легаси-код. Ячейки событий сделали двухслойными картинками. Первый слой - фоновая картинка, второй слой - текст внутри события. Залитая линия справа события это часть фоновой картинки. У события две точки для изменения времени - слева внизу и справа вверху. Им расширили размеры, но фон - прозрачный. Лейаут ячеек на констрейнтах. UINavigationBar базовый, справа добавили Stack View для кнопок. Панель с датами назвали PaletteView. Это UIScrollView и она не является частью UINavigationBar. Всю панель поместили над контентом, но под баром и присоединили к нижней точке бара. Фон повторили, чтобы скрыть переход. Разметка времени слева сделана на одном слое, текст отрисовали внутри CALayer. Время разместили слева экрана, события сместились вправо. Разметка времени лежит внутри UIVisualEffectView, но визуально применений не нашёл. Как писал выше, событие - это картинка. Чтобы обрабатывать нажатие на картинку, нужно добавить UITapGestureRecognizer. Так инженеры эпл и сделали - для вью каждого дня добавили тап-жест. В вот жест драга добавлен один на весь экран, а не отдельные жесты для каждого события. Экран презентуется как модальный контроллер. Сделан на UITableViewController, вью таблицы назвали EKCalendarItemEditorTableView. Ячейки назвали EKUITableViewCell. Disclosure Indicator справа тоже системные. Ничего уникального в экране не нашёл. Главная вью UIScrollView. При переходе на экран по месяцам, панель с числами PaletteView съезжает вверх. Она остается в памяти, но не видна на экране телефона. А вот панель с днями недели визуально остается на месте, но на самом деле это копия. Оригинальная панель уезжает наверх вместе с PaletteView. Названия месяцев сделаны на UILabel. Месяц разбивается на горизонтальные недели. Контейнер назвали CompactMonthWeekView. Внутри дни недели сделаны через CALayer. Только для текущего дня, который красный кружок, дата это UILabel с красным фоном. Назвали CompactMonthWeekTodayCircle. Лейаут на фреймах. Сепаратор между неделями это UIView с фоном и высотой 0.333. Всплывающая панель это таблица. Ячейки назвали EKUIOccurrenceTableViewCell. Лейаут на констрейнтах. Практически все расстояния между элементами выставили фиксированным значением. Отступ от краев ячейки тоже. Контент ячеек сделан на UILabel. Цветная полоска слева это UIView с фоном. Надписи годов сделали через UILabel. Контейнер для хедера назвали CompactYearViewYearHeader. Месяцы группируются по 3 в линию. Даты внутри месяца и название отрисовали слоем внутри вью, назвали CompactYearMonthView. Сделано на UIScrollView с кастомной системой переиспользования. Сделали таблицей. Ячейки называются EKCalendarChooserCell. Круглые чекмарки слева сделали картинками. Нативный экран без кастомизации. Все интерактивные элементы поддерживают Voice Over и Voice Control. Расставлены подсказки. Управление голосом размечено на каждый час в течение дня. Для событий диктуется заголовок, время, календарь и как можно взаимодействовать с элементом. На экране года Voice Control только для месяцев. Voice Over для года и названия месяцев. Accessibility добавлен по всему приложению.  iOS разработчик