ioscalendarswiftuieventkit

SwiftUI EKEventEditViewController fields not editable


I have been trying to use EKEventEditViewController with SwiftUI. I tried to follow some suggestions from dev forums as to how to go about adding it with the help of a UIViewControllerRepresentable wrapper with a Coordinator. I am adding the code below.

The EKEventEditViewController is presented correctly but the problem I'm facing is that only some of the fields are editable. I'm attaching a gif showing the interactions.

Has anyone faced this issue ? Here is the code:

import Foundation
import SwiftUI
import EventKitUI

let eventStore = EKEventStore()

struct NewEventGenerator: UIViewControllerRepresentable {

typealias UIViewControllerType = EKEventEditViewController

@Binding var isShowing: Bool

var theEvent = EKEvent.init(eventStore: eventStore)

func makeUIViewController(context: UIViewControllerRepresentableContext<NewEventGenerator>) -> EKEventEditViewController {

    let controller = EKEventEditViewController()
    controller.event = theEvent
    controller.eventStore = eventStore
    controller.editViewDelegate = context.coordinator

    return controller
}

func updateUIViewController(_ uiViewController: NewEventGenerator.UIViewControllerType, context: UIViewControllerRepresentableContext<NewEventGenerator>) {
    uiViewController.view.backgroundColor = .red
}


func makeCoordinator() -> Coordinator {
    return Coordinator(isShowing: $isShowing)
}

class Coordinator : NSObject, UINavigationControllerDelegate, EKEventEditViewDelegate {

    @Binding var isVisible: Bool

    init(isShowing: Binding<Bool>) {
        _isVisible = isShowing
    }

    func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        switch action {
        case .canceled:
            isVisible = false
        case .saved:
            do {
                try controller.eventStore.save(controller.event!, span: .thisEvent, commit: true)
            }
            catch {
                print("Event couldn't be created")
            }
            isVisible = false
        case .deleted:
            isVisible = false
        @unknown default:
            isVisible = false
        }
    }
}}

Here is the recording


Solution

  • Works fine with Xcode 12 / iOS 14. Literally copy-pasted your code added requestAccess & descriptions in Info.plist.

    demo

    Full tested module, for the case if something might be helpful.

    import SwiftUI
    import EventKitUI
    
    let eventStore = EKEventStore()
    
    struct NewEventGenerator: UIViewControllerRepresentable {
        typealias UIViewControllerType = EKEventEditViewController
    
        @Binding var isShowing: Bool
        var theEvent: EKEvent
    
        init(isShowing: Binding<Bool>) {
            eventStore.requestAccess(to: .event) { allow, error in
                print("Result: \(allow) or [\(error.debugDescription)]")
            }
    
            theEvent = EKEvent.init(eventStore: eventStore)
    
            _isShowing = isShowing
        }
    
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<NewEventGenerator>) -> EKEventEditViewController {
    
        let controller = EKEventEditViewController()
        controller.event = theEvent
        controller.eventStore = eventStore
        controller.editViewDelegate = context.coordinator
    
        return controller
    }
    
    func updateUIViewController(_ uiViewController: NewEventGenerator.UIViewControllerType, context: UIViewControllerRepresentableContext<NewEventGenerator>) {
        uiViewController.view.backgroundColor = .red
    }
    
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(isShowing: $isShowing)
    }
    
    class Coordinator : NSObject, UINavigationControllerDelegate, EKEventEditViewDelegate {
    
        @Binding var isVisible: Bool
    
        init(isShowing: Binding<Bool>) {
            _isVisible = isShowing
        }
    
        func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
            switch action {
            case .canceled:
                isVisible = false
            case .saved:
                do {
                    try controller.eventStore.save(controller.event!, span: .thisEvent, commit: true)
                }
                catch {
                    print("Event couldn't be created")
                }
                isVisible = false
            case .deleted:
                isVisible = false
            @unknown default:
                isVisible = false
            }
        }
    }}
    
    struct TestEventKitViewInSheet: View {     // just created in ContentView body
        @State private var showIt = false
        var body: some View {
            Button("Events") { showIt = true }
                .sheet(isPresented: $showIt) {
                    NewEventGenerator(isShowing: $showIt)
                }
        }
    }