快速重复设置本地通知

时间:2019-03-23 22:56:53

标签: swift xcode uidatepicker timepicker localnotification

我正试图迅速设置每日重复通知。

我可以使用

设置通知
var dateComponents = DateComponents()
dateComponents.hour = 17
dateComponents.minute = 00

但是我希望用户能够更改它,我设置了一个日期选择器并将其更改为仅时间

在日期选择器中,我可以通过执行以下操作来保存它

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    loadDate(animation: true)
}

func saveDate() {
    UserDefaults.standard.set(TimePicker.date, forKey:dateKey)
}

func loadDate(animation: Bool) {
    guard let loadedDate = UserDefaults.standard.object(forKey: dateKey) as? NSDate else { return }

    TimePicker.setDate(loadedDate as Date, animated: animation)
}

如何将从小时和分钟中选择的内容传递到通知时间?另外,如果他们选择下午5点将日期部分设置为17,该如何将时间转换为24小时?

感谢您的帮助

这就是我拥有视图控制器的方式。内部viewdidload。然后时间选择器在另一个viewcontroller内

let center = UNUserNotificationCenter.current()

center.requestAuthorization(options: [.alert, .sound ]){(grandted,error)in }


let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Body"

var dateComponents = DateComponents()
dateComponents.hour = 17
dateComponents.minute = 18

let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)


let uuidstring = UUID().uuidString

let request = UNNotificationRequest(identifier: uuidstring, content: content, trigger: trigger)

center.add(request) {(error) in}

1 个答案:

答案 0 :(得分:0)

由于您在另一个视图控制器上选择了时间(第二个),因此您需要通知第一(主)视图控制器日期已更改。

有很多不同的方法可以做到这一点。 https://codesandbox.io/s/73m8y02x20
选择您喜欢的任何内容,在此示例中,我将使用通知:

extension Notification.Name {
    /// Notification used to pass user selected date
    static let dateChanged = Notification.Name(rawValue: "DateChanged")
}

在第二个控制器更新保存功能中:

func saveDate() {
    UserDefaults.standard.set(TimePicker.date, forKey:dateKey)
    /// Send notification with new time
    NotificationCenter.default.post(name: .dateChanged, object: TimePicker.date)
}

同时在主控制器中,您需要订阅通知:

deinit {
    /// We need to unsubscribe from notifications, otherwise app can crash
    NotificationCenter.default.removeObserver(self)
}

override func viewDidLoad() {
    super.viewDidLoad()
    ...
    /// Subscribe to notifications 
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(dateChanged(_:)),
        name: .dateChanged,
        object: nil
    )
}

/// This method will be called when controller receive notification
/// It need to be annotated with @objc
@objc func dateChanged(_ notification: Notification) {
    let date = notification.object as! Date
    let components = Calendar.current.dateComponents([.hour, .minute], from: date)
    setNotification(with: components)
}

/// By always using same ID for local notifications 
/// You can easily remove them when time changes
private static let notificationID = "MyAppNotificationID"

func setNotification(with components: DateComponents) {
    /// Remove previously planned notification
    center.removePendingNotificationRequests(withIdentifiers: [MainVC.notificationID])

    /// Create new notificaion
    let content = UNMutableNotificationContent()
    content.title = "Title"
    content.body = "Body"
    let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
    let request = UNNotificationRequest(identifier: MainVC.notificationID, content: content, trigger: trigger)

    /// Add to center
    center.add(request) {(error) in}
}