How to call DayViewController's create event from SwiftUI

235 Views Asked by At

I have followed this stackoverflow answer to bridge a custom DayViewController with a SwiftUI view. And it is all working great. Except, when I need to create a new event I open up a .sheet() to let the users edit the event. (I have a custom struct that holds other details about the event, although in the initialization of the DayViewController I manually turn these structs into an Event for the DayViewController). Hence, because the user can edit the event. I don't want to add it to the events list until they are done editing the info in the sheet in SwiftUI. But I can't figure out how to add an event once the editing is done since the editing is done in SwiftUI and I need to create the Event through the create() func in the DayViewController CustomDayViewController-

import UIKit
import CalendarKit

class CalendarController: DayViewController {
    
    convenience init(newVM: AvailabilityViewModel){
        self.init()
        
        self.availabilityViewModel = newVM
    }
    var availabilityViewModel = AvailabilityViewModel(newMapper: APIMapper(), newUser: User(id: 0, first_name: "test", last_name: "man", username: "testman", email: "[email protected]", user_password: "test123"))
    
    var generatedEvents = [EventDescriptor]()
    var alreadyGeneratedSet = Set<Date>()
    
    var colors = [UIColor.blue,
                  UIColor.yellow,
                  UIColor.green,
                  UIColor.red]

    private lazy var rangeFormatter: DateIntervalFormatter = {
      let fmt = DateIntervalFormatter()
      fmt.dateStyle = .none
      fmt.timeStyle = .short

      return fmt
    }()

    override func loadView() {
      calendar.timeZone = TimeZone(identifier: "MST")!

      dayView = DayView(calendar: calendar)
      view = dayView
    }
      
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "CalendarKit Demo"
        navigationController?.navigationBar.isTranslucent = false
        dayView.autoScrollToFirstEvent = true
        reloadData()
    }
      
      // MARK: EventDataSource
      
    override func eventsForDate(_ date: Date) -> [EventDescriptor] {
        var events = [Event]()
        
        while availabilityViewModel.dataLoaded == false {
            
        }
        
        if let availabilities = availabilityViewModel.timeslots[date] {
            for availability in availabilities {
                let event = Event()
                
                event.startDate = availability.start_time
                event.endDate = availability.end_time
                event.text = availability.availability_type
                event.color = getColorForType(availability.availability_type)
                
                events.append(event)
            }
        }
        return events
    }
    
    
    private func getColorForType(_ availability: String) -> UIColor {
        if availability == "preferred"{
            return UIColor.green
        }
        else if availability == "maybe" {
            return UIColor.yellow
        }
        else {
            return UIColor.red
        }
    }
      
    private func textColorForEventInDarkTheme(baseColor: UIColor) -> UIColor {
      var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
      baseColor.getHue(&h, saturation: &s, brightness: &b, alpha: &a)
      return UIColor(hue: h, saturation: s * 0.3, brightness: b, alpha: a)
    }
      
    // MARK: DayViewDelegate
    
    private var createdEvent: EventDescriptor?
    
    override func dayViewDidSelectEventView(_ eventView: EventView) {
      guard let descriptor = eventView.descriptor as? Event else {
        return
      }
      print("Event has been selected: \(descriptor) \(String(describing: descriptor.userInfo))")
    }
      
    override func dayViewDidBeginDragging(dayView: DayView) {
      endEventEditing()
      print("DayView did begin dragging")
    }
    
    override func dayView(dayView: DayView, willMoveTo date: Date) {
      print("DayView = \(dayView) will move to: \(date)")
    }
    
    override func dayView(dayView: DayView, didMoveTo date: Date) {
      print("DayView = \(dayView) did move to: \(date)")
    }
      
    override func dayView(dayView: DayView, didLongPressTimelineAt date: Date) {
        // Cancel editing current event and start creating a new one
        
        endEventEditing()
        
        availabilityViewModel.StartNewAvailability(startDate: MoveTimeToNearestHalfHour(dateToMove: date))
          
        availabilityViewModel.ShowDateEditor()
    }
    
    private func MoveTimeToNearestHalfHour(dateToMove: Date) -> Date {
        //convert to DateComponent
        let calendar = Calendar.current
        var components = calendar.dateComponents([Calendar.Component.year, Calendar.Component.month, Calendar.Component.day,Calendar.Component.hour, Calendar.Component.minute], from: dateToMove)
        
        if components.minute! < 30 {
            components.minute = 0
        }
        else {
            components.minute = 30
        }
        
        return calendar.date(from: components) ?? dateToMove
    }
        
    override func dayView(dayView: DayView, didUpdate event: EventDescriptor) {
      print("did finish editing \(event)")
      print("new startDate: \(event.startDate) new endDate: \(event.endDate)")
    }
}

BridgerController

import SwiftUI
import UIKit

struct BridgerController: UIViewControllerRepresentable  {
    @ObservedObject var availabilityViewModel: AvailabilityViewModel
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
    }
    
    func makeUIViewController(context: Context) -> some UIViewController {
        let dayViewController = CalendarController(newVM:availabilityViewModel)
        return dayViewController
    }
}

I've tried creating a override of the create function in my Custom DayViewController. But, I have no way to access it from SwiftUI.

Any help would be appreciated!

0

There are 0 best solutions below