I’m attempting to implement CalendarKit using SwiftUI’s UIViewControllerRepresentable
. The example provided by the library is in UIKit. I’ve successfully displayed the UI, but when I try to pass dummy events data to display events in CalendarKit, the DayViewDelegate
and EventDataSource
methods inside the coordinator class are not being called, and no data is being displayed.
What am I doing wrong, or how can I achieve this? Any kind of help would be appreciated.
My SwiftUI Representable Code:
import SwiftUI
import CalendarKit
struct DayViewControllerWrapper: UIViewControllerRepresentable {
@Binding var selectedEvent: Event?
@Binding var events: [EventDescriptor]
// Callbacks for coordinator delegates
var didSelectEventView: ((EventView) -> Void)?
var didLongPressEventView: ((EventView) -> Void)?
var didTapTimelineAt: ((Date) -> Void)?
var didLongPressTimelineAt: ((Date) -> Void)?
var didBeginDragging: (() -> Void)?
var didTransitionCancel: (() -> Void)?
var willMoveTo: ((Date) -> Void)?
var didMoveTo: ((Date) -> Void)?
var didUpdateEvent: ((EventDescriptor) -> Void)?
func makeUIViewController(context: Context) -> DayViewController {
let viewController = DayViewController()
// Set up bindings for delegates and data sources
viewController.dataSource = context.coordinator
viewController.delegate = context.coordinator
return viewController
}
func updateUIViewController(_ uiViewController: DayViewController, context: Context) {
uiViewController.reloadData()
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, EventDataSource, DayViewDelegate {
var parent: DayViewControllerWrapper
init(_ parent: DayViewControllerWrapper) {
self.parent = parent
}
// MARK: - EventDataSource
func eventsForDate(_ date: Date) -> [EventDescriptor] {
return parent.events
}
// MARK: - DayViewDelegate
func dayViewDidSelectEventView(_ eventView: EventView) {
parent.selectedEvent = eventView.descriptor as? Event
parent.didSelectEventView?(eventView)
}
func dayViewDidLongPressEventView(_ eventView: EventView) {
parent.didLongPressEventView?(eventView)
}
func dayView(dayView: DayView, didTapTimelineAt date: Date) {
parent.didTapTimelineAt?(date)
}
func dayView(dayView: DayView, didLongPressTimelineAt date: Date) {
parent.didLongPressTimelineAt?(date)
}
func dayViewDidBeginDragging(dayView: DayView) {
parent.didBeginDragging?()
}
func dayViewDidTransitionCancel(dayView: DayView) {
parent.didTransitionCancel?()
}
func dayView(dayView: DayView, willMoveTo date: Date) {
parent.willMoveTo?(date)
}
func dayView(dayView: DayView, didMoveTo date: Date) {
parent.didMoveTo?(date)
}
func dayView(dayView: DayView, didUpdate event: EventDescriptor) {
parent.didUpdateEvent?(event)
}
}
}
struct DayViewControllerWrapper_Previews: PreviewProvider {
static var previews: some View {
DayViewControllerWrapper(selectedEvent: .constant(nil), events: .constant([]))
}
}
My ContentView code, how i’m using it.
import SwiftUI
import CalendarKit
struct ContentView: View {
@State private var selectedEvent: Event?
@State private var events: [EventDescriptor] = []
var body: some View {
VStack {
Text("My Custom Calendar Example")
DayViewControllerWrapper(
selectedEvent: $selectedEvent,
events: $events,
didSelectEventView: { eventView in
// Handle event selection
print("Selected event: \(eventView.descriptor)")
},
didLongPressEventView: { eventView in
// Handle long press event
print("Long pressed event: \(eventView.descriptor)")
},
didTapTimelineAt: { date in
// Handle tap on timeline
print("Tapped timeline at: \(date)")
},
didLongPressTimelineAt: { date in
// Handle long press on timeline
print("Long pressed timeline at: \(date)")
},
didBeginDragging: {
// Handle begin dragging
print("Began dragging")
},
didTransitionCancel: {
// Handle transition cancel
print("Transition canceled")
},
willMoveTo: { date in
// Handle will move to date
print("Will move to date: \(date)")
},
didMoveTo: { date in
// Handle did move to date
print("Did move to date: \(date)")
},
didUpdateEvent: { event in
// Handle updating event
print("Updated event: \(event)")
}
)
.frame(height: 400) // Adjust frame height as needed
.onAppear {
// Populate events with dummy data
generateDummyData()
}
}
}
private func generateDummyData() {
events = [
createEvent(title: "Breakfast at Tiffany's", location: "New York, 5th avenue"),
createEvent(title: "Workout", location: "Tufteparken"),
createEvent(title: "Meeting with Alex", location: "Home, Oslo, Tjuvholmen"),
createEvent(title: "Beach Volleyball", location: "Ipanema Beach, Rio De Janeiro"),
createEvent(title: "WWDC", location: "Moscone West Convention Center, 747 Howard St"),
createEvent(title: "Google I/O", location: "Shoreline Amphitheatre, One Amphitheatre Parkway"),
createEvent(title: "✈️️ to Svalbard ❄️️❄️️❄️️❤️️", location: "Oslo Gardermoen"),
createEvent(title: "💻📲 Developing CalendarKit", location: "🌍 Worldwide"),
createEvent(title: "Software Development Lecture", location: "Mikpoli MB310, Craig Federighi")
]
}
private func createEvent(title: String, location: String) -> EventDescriptor {
let event = Event()
event.startDate = Date()
event.endDate = Date().addingTimeInterval(3600)
event.text = "\(title)\n\(location)"
event.color = .blue
event.isAllDay = false
event.userInfo = nil
return event
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Library provided UIKit example code:
https://github.com/richardtop/CalendarKit/blob/master/CalendarKitDemo/CalendarApp/CustomCalendarExampleController.swift