简体   繁体   English

EKCalendarChooser 委托不能在 NSObject 中工作

[英]EKCalendarChooser delegate not working from within NSObject

I have an NSObject class that consists of a basic EKCalendarChooser implementation and I am unable to get the delegate functions calendarChooserDidFinish , calendarChooserSelectionDidChange , and calendarChooserDidCancel working.我有一个 NSObject 类,它包含一个基本的 EKCalendarChooser 实现,但我无法使委托函数calendarChooserDidFinishcalendarChooserSelectionDidChangecalendarChooserDidCancel工作。 I'm not sure if it is the fact that everything is in an NSObject but I wanted to keep this code separate from my other files.我不确定是否所有内容都在 NSObject 中,但我想将此代码与其他文件分开。

I've tried a lot of troubleshooting such as not keeping the delegate methods under an extension and even making a global variable for the EKCalendarChooser as I found this post which states that non-global items could be dereferenced in contexts like this.我已经尝试了很多故障排除,例如不将委托方法保留在扩展名下,甚至为 EKCalendarChooser 创建一个全局变量,因为我发现这篇文章指出非全局项可以在这样的上下文中取消引用。 Overall I can get the controller to pop up and it's just the way I want, but the delegate methods don't work.总的来说,我可以让控制器弹出,这正是我想要的方式,但委托方法不起作用。 Below is the entire code and in my main viewController I get this to show with AddAppointments(parentViewController: self).chooseCalendarTapped()下面是整个代码,在我的主视图控制器中,我用AddAppointments(parentViewController: self).chooseCalendarTapped()显示了这个

import UIKit
import EventKitUI

class Cal: NSObject {
    
    let eventStore = EKEventStore()
    var parentViewController: UIViewController
    var CalendarChooser: EKCalendarChooser = EKCalendarChooser()
    
    init(parentViewController: UIViewController) {
           self.parentViewController = parentViewController
           super.init()
    }
   

  func chooseCalendarTapped() {
        let authStatus = EKEventStore.authorizationStatus(for: .event)
        
        switch authStatus {
        case .authorized:
            showCalendarChooser()
        case .notDetermined:
            requestAccess()
        case .denied:
            // Explain to the user that they did not give permission
            break
        case .restricted:
            break
        @unknown default:
            preconditionFailure("Who knows what the future holds 🤔")
        }
    }
    
    func requestAccess() {
        eventStore.requestAccess(to: .event) { (granted, error) in
            if granted {
                // may not be called on the main thread..
                DispatchQueue.main.async {
                    self.showCalendarChooser()
                }
            }
        }
    }
    
    func showCalendarChooser() {
        CalendarChooser = EKCalendarChooser(selectionStyle: .single, displayStyle: .allCalendars, entityType: .event, eventStore: eventStore)
        
        // customization
        CalendarChooser.showsDoneButton = true
        CalendarChooser.showsCancelButton = true
        
        // dont forget the delegate
        CalendarChooser.delegate = self
        
        let nvc = UINavigationController(rootViewController: CalendarChooser)
        parentViewController.present(nvc, animated: true, completion: nil)
    }
    
    
    
}

extension Cal : EKCalendarChooserDelegate {
    func calendarChooserDidFinish(_ calendarChooser: EKCalendarChooser) {
        print(calendarChooser.selectedCalendars)
     //   dismiss(animated: true, completion: nil)
    }
    
    func calendarChooserSelectionDidChange(_ calendarChooser: EKCalendarChooser) {
        print("Changed selection")
    }
    
    func calendarChooserDidCancel(_ calendarChooser: EKCalendarChooser) {
        print("Cancel tapped")
     //   dismiss(animated: true, completion: nil)
    }
}

Check if this works now:检查这现在是否有效:

Declaring a var at the controller class level works here instead of having a new instance inside a function:在控制器类级别声明 var 在这里工作,而不是在函数内有一个新实例:

Controller :控制器

class HomeVC: UIViewController {
    var event = EventManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        event.chooseCalendarTapped(presentingVC: self)
    }
}

EventManager Class :事件管理器类

import UIKit
import EventKitUI

class EventManager: NSObject {
    
    let eventStore = EKEventStore()

    override init() {
           super.init()
       }
    
    weak var delegate: EKCalendarChooserDelegate? = nil
    
    var presentingVC: UIViewController? = nil
    

    func chooseCalendarTapped(presentingVC: UIViewController) {
        
        self.presentingVC = presentingVC
        
        let authStatus = EKEventStore.authorizationStatus(for: .event)
        
        switch authStatus {
        case .authorized:
            showCalendarChooser()
        case .notDetermined:
            requestAccess()
        case .denied:
            // Explain to the user that they did not give permission
            break
        case .restricted:
            break
        @unknown default:
            preconditionFailure("Who knows what the future holds 🤔")
        }
    }
    
    func requestAccess() {
        eventStore.requestAccess(to: .event) { (granted, error) in
            if granted {
                // may not be called on the main thread..
                DispatchQueue.main.async {
                    self.showCalendarChooser()
                }
            }
        }
    }
    
    func showCalendarChooser() {
        let vc = EKCalendarChooser(selectionStyle: .single, displayStyle: .allCalendars, entityType: .event, eventStore: eventStore)
        
        // customization
        vc.showsDoneButton = true
        vc.showsCancelButton = true
        
        // dont forget the delegate
        vc.delegate = self
        
        let nvc = UINavigationController(rootViewController: vc)
        
        presentingVC?.present(nvc, animated: true, completion: nil)
    }
}

extension EventManager: EKCalendarChooserDelegate {
    func calendarChooserDidFinish(_ calendarChooser: EKCalendarChooser) {
        print(calendarChooser.selectedCalendars)
        presentingVC?.dismiss(animated: true, completion: nil)
    }
    
    func calendarChooserSelectionDidChange(_ calendarChooser: EKCalendarChooser) {
        print("Changed selection")
    }
    
    func calendarChooserDidCancel(_ calendarChooser: EKCalendarChooser) {
        print("Cancel tapped")
        presentingVC?.dismiss(animated: true, completion: nil)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM