Реализация собственного календаря с использованием UICalendarView на Swift в iOS 16
Victor
Настройка UICalendarView
UICalendarView принадлежит к фреймворку UIKit и поставляется с простым инициализатором.
let calendarView = UICalendarView() let gregorianCalendar = Calendar(identifier: .gregorian) calendarView.calendar = gregorianCalendar
Примечание. Apple сообщает нам, что необходимо явно указать тип календаря при создании объекта UICalendarView. В нашем примере это будет григорианский календарь.
Доступность API: UICalendarView доступен для iOS16.0+, iPadOS16.0+ и macCatalyst16.0+.
Настройка UICalendarView

UICalendarView поддерживает различные настройки, такие как установка цвета фона, установка радиуса для самой вью, изменение цвета оттенка календаря и многое другое.
calendarView.backgroundColor = .secondarySystemBackground calendarView.layer.cornerCurve = .continuous calendarView.layer.cornerRadius = 10.0 calendarView.tintColor = .orange
Декораторы UICalendarView

У UICalendarView есть делегат UICalendarViewDelegate, который позволяет нам добавлять кастомизацию для конкретных дат. Это будет полезно при отображении свободных/занятых дней в календаре. Убедитесь, что вы также настроили сам делегат.
calendarView.delegate = self
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
let font = UIFont.systemFont(ofSize: 14)
let configuration = UIImage.SymbolConfiguration(font: font)
let image = UIImage(systemName: "music.note", withConfiguration: configuration)?.withRenderingMode(.alwaysOriginal)
return .image(image)
}
В приведенном выше примере мы добавили ноту ко всем датам в календаре. Вы можете написать свою логику для настройки декораторов.
Ограничение выбора даты
Вы также можете указать диапазоны дат, которые может выбрать пользователь. В приведенном выше примере вы можете видеть, что даты до текущей даты недоступны.
calendarView.availableDateRange = DateInterval.init(start: Date.now, end: Date.distantFuture)
Выбор дат в UICalendarView
В UICalendarView существует два типа такого выбора: выбор одной даты и выбор нескольких дат. Необходимость выбора одной или нескольких дат должна быть указана в свойстве selectionBehaviour у нашего календаря.
Для одиночного выбора
let dateSelection = UICalendarSelectionSingleDate(delegate: self) calendarView.selectionBehavior = dateSelection
Для мультивыбора
let dateSelection = UICalendarSelectionMultiDate(delegate: self) calendarView.selectionBehavior = dateSelection
Выбор одной даты в UICalendarView
Выбор одной даты в UICalendarView выполняется с помощью UICalendarSelectionSingleDateDelegate. Делегат предоставляет нам два метода.
func dateSelection(_ selection: UICalendarSelectionSingleDate, didSelectDate dateComponents: DateComponents?) {
print("Selected Date:", dateComponents)
}
func dateSelection(_ selection: UICalendarSelectionSingleDate, canSelectDate dateComponents: DateComponents?) -> Bool {
return true
}
Метод didSelectDate показывает нам дату всякий раз, когда пользователь нажимает дату в UICalendarView. Метод canSelectDate — это необязательный метод делегата, с помощью которого вы можете решить, разрешать ли пользователю выбирать конкретную дату или нет.
Выбор нескольких дат в UICalendarView

Выбор нескольких дат в UICalendarView выполняется с помощью UICalendarSelectionMultiDateDelegate. Делегат предоставляет нам следующие методы.
func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didSelectDate dateComponents: DateComponents) {
print("Selected Date:", dateComponents)
}
Метод didSelectDate показывает дату, выбранную пользователем.
func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didDeselectDate dateComponents: DateComponents) {
print("De-Selected Date:", dateComponents)
}
Метод didDeselectDate, наоборот, показывает дату, которую пользователь отменил.
func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canSelectDate dateComponents: DateComponents) -> Bool {
return true
}
func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canDeselectDate dateComponents: DateComponents) -> Bool {
return true
}
canSelectDate и canDeselectDate — это опциональные методы делегата, с помощью которых вы можете решить, разрешить ли пользователю выбирать/отменять выбор определенной даты или нет.
В целом, UICalendarView это точно значительное улучшение по сравнению с UIDatePicker.
Пример кода можно найти здесь.
А про разработку можно прочитать в моём авторском канале.
