问题描述
我有一个 NSObject 类,它包含一个基本的 EKCalendarChooser 实现,但我无法使委托函数 calendarChooserDidFinish
、calendarChooserSelectionDidChange
和 calendarChooserDidCancel
正常工作。我不确定一切是否都在 NSObject 中,但我想将此代码与其他文件分开。
我尝试了很多故障排除方法,例如不将委托方法保留在扩展名下,甚至为 EKCalendarChooser 创建一个全局变量,因为我发现 this post 指出可以在上下文中取消引用非全局项像这样。总的来说,我可以让控制器弹出,这正是我想要的方式,但委托方法不起作用。下面是整个代码,在我的主视图控制器中,我用 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)
}
}
解决方法
检查现在是否有效:
在控制器类级别声明一个 var 在这里工作,而不是在函数内有一个新实例:
控制器:
class HomeVC: UIViewController {
var event = EventManager()
override func viewDidLoad() {
super.viewDidLoad()
event.chooseCalendarTapped(presentingVC: self)
}
}
EventManager 类:
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)
}
}