How to use EKCalendarChooser with SwiftUI
Short post showing how to bridge this controller with SwiftUI and get selected calendars.
Published: Aug. 1, 2020 Sponsored I want a Press KitJust like other UIKit controllers EKCalendarChooser
, which lets users select their calendars, for use in your app needs a small wrapper around it with the UIViewControllerRepresentable
protocol.
This code below is intended as a starting point for folks who need to work with EKCalendarChooser
in their SwiftUI project.
Big thanks to Paul Hudson for this guide about using UIImagePickerController
with SwiftUI which served as an inspiration.
Complete code
So here is the code:
import SwiftUI
import EventKitUI
struct CalendarChooser: UIViewControllerRepresentable {
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
@Environment(\.presentationMode) var presentationMode
@Binding var calendars: Set<EKCalendar>?
let eventStore: EKEventStore
func makeUIViewController(context: UIViewControllerRepresentableContext<CalendarChooser>) -> UINavigationController {
let chooser = EKCalendarChooser(selectionStyle: .multiple, displayStyle: .allCalendars, entityType: .event, eventStore: eventStore)
chooser.selectedCalendars = calendars ?? []
chooser.delegate = context.coordinator
chooser.showsDoneButton = true
chooser.showsCancelButton = true
return UINavigationController(rootViewController: chooser)
}
func updateUIViewController(_ uiViewController: UINavigationController, context: UIViewControllerRepresentableContext<CalendarChooser>) {
}
class Coordinator: NSObject, UINavigationControllerDelegate, EKCalendarChooserDelegate {
let parent: CalendarChooser
init(_ parent: CalendarChooser) {
self.parent = parent
}
func calendarChooserDidFinish(_ calendarChooser: EKCalendarChooser) {
parent.calendars = calendarChooser.selectedCalendars
parent.presentationMode.wrappedValue.dismiss()
}
func calendarChooserDidCancel(_ calendarChooser: EKCalendarChooser) {
parent.presentationMode.wrappedValue.dismiss()
}
}
}
Example usage
Sample usage can look something like this:
.sheet(isPresented: $showingCalendarChooser) {
CalendarChooser(calendars: self.$eventsRepository.selectedCalendars, eventStore: self.eventsRepository.eventStore)
}
You need to pass in Binding
for selected calendars and also instance of EKEventStore
.
I am using this definition for selectedCalendars
:
@Published var selectedCalendars: Set<EKCalendar>?
More EventKit resources
For more on EventKit check out other posts in this series or my example project on GitHub.
Uses: Xcode 12 & Swift 5.3