EKEventEditViewController 显示有一个禁用的添加按钮

EKEventEditViewController is presented with a disabled Add button

问题

我正在展示一个包含一些预定义信息的 EKEventEditViewController 视图。如果用户不想更改此信息,他应该能够点击添加以将事件添加到日历中。

问题是,默认情况下禁用“添加”按钮。它仅在用户更改某些内容(例如事件名称或日历)时启用。

代码片段

class EventManager {

    private var eventEditViewController: EKEventEditViewController?
    private let eventStore = EKEventStore()

    func addToCalendar(_ eventData: EventData) {
        let event = createEvent(eventData)
        presentEvent(event)
    }

    private func createEvent(_ eventData: EventData) -> EKEvent {
        let event = EKEvent(eventStore: eventStore)
        event.title = "My event"
        event.startDate = Date()
        event.endDate = Date()
        event.isAllDay = true
        event.calendar = eventStore.defaultCalendarForNewEvents
        event.availability = .free
        event.addAlarm(EKAlarm.init(absoluteDate: event.startDate))
        event.url = URL(string: "http://myurl.com/")
        return event
    }

    private func presentEvent(_ event: EKEvent) {
        DispatchQueue.main.async {
            self.eventEditViewController = EKEventEditViewController()
            self.eventEditViewController!.eventStore = self.eventStore
            self.eventEditViewController!.event = event
            self.eventEditViewController!.editViewDelegate = self

            self.viewController?.present(self.eventEditViewController!, animated: true)
        }
    }

}

extension EventManager: EKEventEditViewDelegate {

    func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        eventEditViewController?.dismiss(animated: true, completion: {
            self.delegate.finish(result: CalendarResult.fromAction(action))
        })
    }

}

EKEventEditViewController

EKEventEditViewController 的呈现方式如下:

还有一件事

我注意到的另一件事是,当我从 EKEvent 对象中删除开始日期和结束日期时,默认情况下会启用“添加”按钮。

如何配置我的 EKEvent 对象,使其具有自定义的开始和结束日期,同时默认启用 EKEventEditViewController 的添加按钮?

这已在 iOS 13.3 beta

中修复

On iOS 12.2.x:显然 EKEventEditViewController 将您的事件视为已经存在的事件事件而不是新事件。因此禁用 Add 按钮,因为没有进行任何更改(Apple bug)。

证明它的一个小方法是尝试通过删除一个字符来编辑标题,这将启用添加,因为现在它与原来的不同。如果您放回刚刚删除的相同字符,它将再次禁用“添加”按钮。

我们发现的解决方法是像这样子类化 EKEventEditViewController

final class FixedEventEditViewController: EKEventEditViewController {
    /// Set this variable instead of the `event` property to avoid a crash on iOS 12+ when a fixed timezone is set
    var deferredEvent: EKEvent?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if let deferredEvent = self.deferredEvent {
            // Trick iOS into thinking that the event changed so it enables the Add button on iOS 13.2.x -> Fixed starting iOS 13.3
            let titleDeferred = deferredEvent.title
            deferredEvent.title = nil
            // Set the event to the new deferred event that contains no title
            self.event = deferredEvent
            // Set the original title. This will let iOS think the event changed and enable the Add button
            self.event?.title = titleDeferred
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // This is to hide the keyboard
        self.view.endEditing(true)
    }
}