Presenting a EKEventEditViewController from SwiftUI View

Replies

Does this help?

https://stackoverflow.com/questions/56784722/swiftui-send-email


I'd be interested in your code once you figure it out.

I'll look into it. Thanks!

I'm seeing errors on MailView.swift.


Cannot assign to property: '$isShowing' is immutable

Cannot assign to property: '$result' is immutable

I've actually made progress on this, but my current problem is how do I ask for calendar event permission from with a SwiftUI view? The alert will not be shown.

I was able to bring up the EKEventEditViewConttroller, but no delegate, so could not handle the result.

The trick is to embed it inside a ZStack and make it appear via an @Binding.


import Foundation
import SwiftUI
import EventKitUI

let eventStore = EKEventStore()
struct EKEventWrapper: UIViewControllerRepresentable {
    @Binding var isShown: Bool
    typealias UIViewControllerType = EKEventEditViewController
    var theEvent = EKEvent.init(eventStore: eventStore)
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<EKEventWrapper>) -> EKEventEditViewController {
//        func makeUIViewController(context: UIViewControllerRepresentableContext<EKEventWrapper>) -> EKEventWrapper.UIViewControllerType {
        theEvent.startDate = Date()
        theEvent.endDate = Date()
        theEvent.title = "The Main Event!"
        let calendar = EKCalendar.init(for: .event, eventStore: eventStore)
        theEvent.calendar = calendar
        let controller = EKEventEditViewController()
        controller.event = theEvent
        controller.eventStore = eventStore
        controller.editViewDelegate = context.coordinator
        return controller
    }

    func updateUIViewController(_ uiViewController: EKEventWrapper.UIViewControllerType, context: UIViewControllerRepresentableContext<EKEventWrapper>) {
        //
    }
    
    func makeCoordinator() -> EKEventWrapper.Coordinator {
        return Coordinator(isShown: $isShown, event: theEvent)
    }
      
    class Coordinator : NSObject, UINavigationControllerDelegate, EKEventEditViewDelegate {
        @Binding var isShown: Bool
        
        init(isShown: Binding<Bool>, event: EKEvent) {
            _isShown = isShown
        }
        
        func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
            switch action {
            case .canceled:
                print("Canceled")
                isShown = false
//                controller.dismiss(animated: true, completion: nil)
            case .saved:
                print("Saved")
                do {
                    try controller.eventStore.save(controller.event!, span: .thisEvent, commit: true)
                }
                catch {
                    print("Problem saving event")
                }
                isShown = false
//                controller.dismiss(animated: true, completion: nil)
            case .deleted:
                print("Deleted")
                isShown = false
//                controller.dismiss(animated: true, completion: nil)
            @unknown default:
                print("I shouldn't be here")
                isShown = false
//                controller.dismiss(animated: true, completion: nil)
            }
        }
    }
}

Even though this works, it's not how this view controller would normally be shown. But it didn't work modally for several reasons. It worked once, but when I showed it a second time, I could not dismiss it, nor did the delegate fire the second time. But when I navigate out of the detail view and then back in, then it worked again.