如何使用 UIPickerView 的选定值作为通知的时间间隔?

Posted

技术标签:

【中文标题】如何使用 UIPickerView 的选定值作为通知的时间间隔?【英文标题】:How to use selected value of UIPickerView as time interval for notifications? 【发布时间】:2017-04-04 20:51:31 【问题描述】:

我正在尝试从 UIPickerView 中的选定行中获取一个值,并根据选定的行设置重复通知的时间间隔。即,用户在 UIPickerView 中选择“每 2 分钟”,每 120.0 秒收到一次通知。

第二个“didSelectRow”方法似乎没有将值存储在我的变量interval中,到目前为止我还没有找到解决方案。

这是我目前的代码:

import UIKit
import  UserNotifications
import UserNotificationsUI

class ViewController: UIViewcontroller, UIPickerViewDataSource, UIPickerViewDelegate 
    // The following lines define the parameters for Picker View
    @IBOutlet weak var myLabel: UILabel!
    @IBOutlet weak var myPicker: UIPickerView!

    let pickerData = ["Every minute", "Every 2 minutes", "Every 3 minutes", "Every 4 minutes", "Every 5 minutes", "Every 6 minutes", "Every 7 minutes", "Every 8 minutes", "Every 9 minutes", "Every 10 minutes"]

    override func viewDidLoad() 
        super.viewDidLoad()
        myPicker.delegate = self
        myPicker.dataSource = self
    

    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 1
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
            return pickerData.count
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        return pickerData[row]
    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        myLabel.text = pickerData[row]
    

    var interval: TimeInterval = 60.0 // Assume that row 0 is selected by default

    // The following method might be the tricky part I guess.

    func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) 
interval = Double(row+1) * 60.0
    


    let requestIdentifier = "SampleRequest" //identifier is to cancel the notification request

    @IBAction  func triggerNotification()
        print("notification will be triggered in five seconds..Hold on tight")
        let content = UNMutableNotificationContent()
        content.title = "Placeholder"
        content.subtitle = "Placeholder"
        content.body = "Placeholder"
        content.sound = UNNotificationSound.default()

        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval:self.interval, repeats: true)
        let request = UNNotificationRequest(identifier:requestIdentifier, content: content, trigger: trigger)

        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().add(request)(error) in
            if (error != nil)
                print(error?.localizedDescription ?? "User instance is nil")
            
        
    

    @IBAction func stopNotification(_ sender: AnyObject) 

        print("Removed all pending notifications")
        let center = UNUserNotificationCenter.current()
        center.removePendingNotificationRequests(withIdentifiers: [requestIdentifier])
    

谁能帮我解决这个问题?

【问题讨论】:

您需要创建一个与您的时间相对应的值数组,然后使用选择器视图的选定索引从数组中获取值 我不确定我是否可以关注你。值数组意味着包含 60.0、120.0 等的数组?我将如何使用pickerview的选定索引从另一个数组中获取值? 没错。然后只需timeDelay = times[row] 好的,我想我在这里缺乏一些基本知识。您会在pickerView 方法(我目前使用let selected = pickerData[row] 的方法)中执行此操作吗?另外,我如何从pickerData[row] 获得times[row] 的值? 【参考方案1】:

创建一个分钟数组并像这样在分钟数组下声明您的区间变量

let pickerData = ["Every minute", "Every 2 minutes", "Every 3 minutes", "Every 4 minutes", "Every 5 minutes", "Every 6 minutes", "Every 7 minutes", "Every 8 minutes", "Every 9 minutes", "Every 10 minutes"]
let minutes[Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var interval: Inte = 0

将您的 pickerView didSelectRow 函数更改为此

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) 
    interval = minutes[row]

现在您的区间为 int,介于 1 到 10 之间,具体取决于已选择的行。

@IBAction  func triggerNotification()
    print("notification will be triggered in five seconds..Hold on tight")
    let content = UNMutableNotificationContent()
    content.title = "Placeholder"
    content.subtitle = "Placeholder"
    content.body = "Placeholder"
    content.sound = UNNotificationSound.default()

    let minute = TimeInterval(interval * 60)

    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval:(minute), repeats: true)
    let request = UNNotificationRequest(identifier:requestIdentifier, content: content, trigger: trigger)

    UNUserNotificationCenter.current().delegate = self
    UNUserNotificationCenter.current().add(request)(error) in
        if (error != nil)
            print(error?.localizedDescription ?? "User instance is nil")
        
    

我创建了一个新的分钟变量,它是一个 TimeInterval 也乘以间隔*60。如果间隔是 2,那么它将是 2*60 = 120 等等。

【讨论】:

酷,谢谢。但我在let minute: TimeInterval = interval * 60 线上收到以下错误:“二进制运算符'*' 不能应用于两个'Int' 操作数”有什么想法吗? 我更新了示例请再看一遍我更改了分钟数组也让分钟 = TimeInterval(interval*60) 它应该可以解决问题【参考方案2】:

您可以简单地将所选行加 1,然后乘以 60.0:

var interval: TimeInterval = 60.0 // Assume that row 0 is selected by default

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) 
    interval = Double(row+1) * 60.0


@IBAction  func triggerNotification() 

    let content = UNMutableNotificationContent()
    content.title = "Placeholder"
    content.subtitle = "Placeholder"
    content.body = "Placeholder"
    content.sound = UNNotificationSound.default()

    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval:interval, repeats: true)
    let request = UNNotificationRequest(identifier:requestIdentifier, content: content, trigger: trigger)

    UNUserNotificationCenter.current().delegate = self
    UNUserNotificationCenter.current().add(request)(error) in
        if (error != nil)
            print(error?.localizedDescription ?? "User instance is nil")
        
    

【讨论】:

酷,这种作品。但我总是比我应该从选择中获得通知早一分钟(例如,我选择“每 2 分钟”并每分钟获得一次)。这是为什么?一定要加2吗?我还认为它应该是Double(row+1),对吧? 不确定。代码应该是正确的。 rowinterval 的价值是多少? 目前无法查看,因为我在工作,但我稍后会查看。但我只是注意到应用程序每分钟发送一个通知,无论选择了哪一行。知道可能出了什么问题吗? 看来您在安排新通知之前没有取消之前的通知 我也是这么想的,但这不是问题所在。取消它然后再试一次,一分钟后仍然发送它(并重复)。【参考方案3】:

似乎我已经通过执行以下操作解决了它。因为我注意到一切都正常运行,直到我试图将我需要的值存储在 interval 中 - 该方法不会这样做,但之前的方法会正确分配 row

不是这个

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int,          inComponent component: Int) 
    myLabel.text = pickerData[row]


var interval: TimeInterval = 60.0 // Assume that row 0 is selected by default

func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) 
interval = Double(row+1) * 60.0

我在有myLabel.text = pickerData[row]的函数中加入了interval = Double(row+1) * 60.0这一行,像这样:

var interval: TimeInterval = 60.0 // Assume that row 0 is selected by default
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int,          inComponent component: Int) 
    myLabel.text = pickerData[row]
    interval = Double(row+1) * 60.0

这可以工作并将正确的值存储在interval 中,例如当您选择“每 2 分钟”行时,它会存储 120.0。

【讨论】:

以上是关于如何使用 UIPickerView 的选定值作为通知的时间间隔?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据标签显示 UIPickerView 的选定值

UIPickerView 在没有数据源的情况下获取选定的值

如何从UIPickerView获取选定的值

如何更改 UIPickerView 中选定行的颜色

如何更改 UIPickerView 中选定行的颜色

获取 UIPickerView 当前选中的值