Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何获取密钥';s值并完成我的委托_Ios_Swift_Timer_Uipickerview - Fatal编程技术网

Ios 如何获取密钥';s值并完成我的委托

Ios 如何获取密钥';s值并完成我的委托,ios,swift,timer,uipickerview,Ios,Swift,Timer,Uipickerview,我是一个初学者,所以如果这一切看起来很粗糙,我道歉 我有一本以秒为单位的时间和时间量的字典。这是一款带有pickerView的倒计时应用程序,可以让你选择倒计时开始时间,一旦你在pickerView的didSelect中选择了一个时间,它就会用该时间量更新计时器标签。然后,当您轻按“播放”时,它将从该时间量开始播放 我试图使用pickerView的didSelect中的协议来告诉我何时选择了时间,然后将时间与其时间量的值(以秒为单位)进行匹配,将秒转换为小时:分钟:秒,并将该信息传递给计时器,以

我是一个初学者,所以如果这一切看起来很粗糙,我道歉

我有一本以秒为单位的时间和时间量的字典。这是一款带有
pickerView
的倒计时应用程序,可以让你选择倒计时开始时间,一旦你在pickerView的
didSelect
中选择了一个时间,它就会用该时间量更新计时器标签。然后,当您轻按“播放”时,它将从该时间量开始播放

我试图使用pickerView的didSelect中的协议来告诉我何时选择了时间,然后将时间与其时间量的值(以秒为单位)进行匹配,将秒转换为小时:分钟:秒,并将该信息传递给计时器,以便计时器可以从该时间开始播放。然而,我被困于完成代表

我得到了这个错误:当我试图调用协议存根中的密钥值时,无法用“[String]”类型的索引为“[String:Int]”类型的值下标。我知道基本上我有一个数组,我不能从中得到键的值,但我现在需要帮助找出如何向后走。。。从数组返回键和值。我将所有时间都放在pickerView的一个数组中,但我一直在思考如何获取在我给pickerView的时间数组中所选的键的值

以下是我迄今为止的代码,其中错误显示:

import UIKit

class TimerVC: UIViewController, TimerValueInSecondsDelegate {

struct Time {
    let name : String
    let amount : Double
}

let selectedTimes = [Time(name:"3 MIN", amount:180.0),
                     Time(name:"5 MIN", amount:300.0),
                     Time(name:"10 MIN", amount:600.0),
                     Time(name:"15 MIN", amount:900.0)]

var delegate: TimerValueInSecondsDelegate?
var counter = 1 //Starting value of seconds
var timer = Timer()
var isTimerRunning = false //Make sure only one timer is created at a time.
let customWidth: CGFloat = 120
let customHeight: CGFloat = 60

@IBOutlet weak var timePickerView: UIPickerView!
@IBOutlet weak var startTimerButton: UIButton!
@IBOutlet weak var timerNumbers: UILabel! //Countdown label
@IBOutlet weak var cancelTimer: UIButton! //Cancel the timer

override func viewDidLoad() {
    super.viewDidLoad()

    timePickerView.dataSource = self
    timePickerView.delegate = self

    cancelTimer.isHidden = true
    timerNumbers.isHidden = true

    startTimerButton.setImage(UIImage(named : "startTimerButton"), for: UIControlState.normal)
    startTimerButton.setImage(UIImage(named : "pauseTimerButton"), for: UIControlState.selected)
    startTimerButton.addTarget(self, action: #selector(startTimerAction), for: UIControlEvents.touchUpInside)
    self.view.addSubview(startTimerButton)
}

   func getSecondsValue(from time : Time) {
   let timeAmountValue = time.amount
}

@IBAction func startTimerAction(_ sender: UIButton) {

    if startTimerButton.isSelected == true {
        startTimerButton.isSelected = false
        timer.invalidate()
    }else {
        startTimerButton.isSelected = true
        runTimer()
    }

    cancelTimer.isHidden = false
    timerNumbers.isHidden = false
}

@IBAction func cancelTimerAction(_ sender: UIButton) {
    timer.invalidate()
    cancelTimer.isHidden = true
    timerNumbers.isHidden = true
    timerNumbers.text = String(counter)
    counter = 0
    startTimerButton.isSelected = false
    isTimerRunning = false
}

func runTimer() {
    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
    isTimerRunning = true
}

@objc func updateTimer() {
    counter -= 1
    //timerNumbers.text = timeString(time: TimeInterval(counter))
}

func timeString(time:TimeInterval) -> String {
    let hours = Int(time) / 3600
    let minutes = Int(time) / 60 % 60
    let seconds = Int(time) % 60
    return String(format:"%02i:%02i:%02i", hours, minutes, seconds)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

extension TimerVC: UIPickerViewDelegate, UIPickerViewDataSource {
//!! pickerView code below !!//
func numberOfComponents(in pickerView: UIPickerView) -> Int {
    pickerView.subviews.forEach({
        $0.isHidden = $0.frame.height < 1.0
    })
    return 1
}

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

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    let time = selectedTimes[row]
delegate?.getSecondsValue(from: time)
}

func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
    return customHeight
}

//custom pickerView label
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: customWidth, height: customHeight))

    let pickerLabel = UILabel(frame: CGRect(x: 0, y: 0, width: customWidth, height: 50))
    pickerLabel.text = selectedTimes[row].name
    pickerLabel.textAlignment = .center
    view.addSubview(pickerLabel)
    return view
}
}

protocol TimerValueInSecondsDelegate {
func getSecondsValue(from time : Time)
}
导入UIKit
类TimerVC:UIViewController,TimerValueUnsecondsDelegate{
结构时间{
let name:String
出租金额:双倍
}
让选定的时间=[时间(名称:“3分钟”,金额:180.0),
时间(名称:“5分钟”,金额:300.0),
时间(名称:“10分钟”,金额:600.0),
时间(名称:“15分钟”,金额:900.0)]
变量委托:TimerValueUnsecondsDelegate?
变量计数器=1//秒的起始值
var timer=timer()
var isTimerRunning=false//确保一次只创建一个计时器。
让customWidth:CGFloat=120
让自定义高度:CGFloat=60
@ibvar-timePickerView:UIPickerView!
@IBVAR弱启动按钮:UIButton!
@IBOUTLE弱var TIMERNUMBES:UILabel!//倒计时标签
@IBVAR cancelTimer:UIButton!//取消计时器
重写func viewDidLoad(){
super.viewDidLoad()
timePickerView.dataSource=self
timePickerView.delegate=self
cancelTimer.ishiden=true
timerNumbers.ishiden=true
startTimerButton.setImage(UIImage(名为:“startTimerButton”),用于:UIControlState.normal)
startTimerButton.setImage(UIImage(名为:“pauseTimerButton”),用于:UIControlState.selected)
startTimerButton.addTarget(自身,操作:#选择器(startTimerAction),用于:UIControlEvents.touchUpInside)
self.view.addSubview(startTimerButton)
}
func getSecondsValue(从时间:time){
让timeAmountValue=time.amount
}
@iAction func StartTimeAction(u发送方:UIButton){
如果startTimerButton.isSelected==true{
startTimerButton.isSelected=false
timer.invalidate()
}否则{
startTimerButton.isSelected=true
运行计时器()
}
cancelTimer.ishiden=false
timerNumbers.ishiden=false
}
@iAction func CancelTimeAction(\发送方:UIButton){
timer.invalidate()
cancelTimer.ishiden=true
timerNumbers.ishiden=true
timerNumbers.text=字符串(计数器)
计数器=0
startTimerButton.isSelected=false
isTimerRunning=false
}
func运行计时器(){
timer=timer.scheduledTimer(时间间隔:1,目标:self,选择器:#选择器(updateTimer),userInfo:nil,repeats:true)
isTimerRunning=true
}
@objc func updateTimer(){
计数器-=1
//timerNumbers.text=timeString(时间:时间间隔(计数器))
}
func timeString(时间:TimeInterval)->String{
让小时数=整数(时间)/3600
分钟数=整数(时间)/60%60
设秒=整数(时间)%60
返回字符串(格式:“%02i:%02i:%02i”,小时、分钟、秒)
}
重写函数didReceiveMemoryWarning(){
超级。我收到了记忆警告()
//处置所有可以重新创建的资源。
}
}
扩展时间RVC:UIPickerViewDelegate,UIPickerViewDataSource{
//!!下面是pickerView代码//
func numberOfComponents(在pickerView:UIPickerView中)->Int{
pickerView.subviews.forEach({
$0.isHidden=$0.frame.height<1.0
})
返回1
}
func pickerView(pickerView:UIPickerView,numberOfRowsInComponent:Int)->Int{
返回selectedTimes.count
}
func pickerView(pickerView:UIPickerView,didSelectRow行:Int,不完整组件:Int){
让时间=选定的时间[行]
委托?.getSecondsValue(起始:时间)
}
func pickerView(pickerView:UIPickerView,rowHeightForComponent:Int)->CGFloat{
返回高度
}
//自定义pickerView标签
func pickerView(pickerView:UIPickerView,viewForRow行:Int,forComponent组件:Int,重用视图:UIView?->UIView{
let view=ui视图(帧:CGRect(x:0,y:0,宽度:customWidth,高度:customHeight))
让pickerLabel=UILabel(帧:CGRect(x:0,y:0,宽度:customWidth,高度:50))
pickerLabel.text=selectedTimes[row]。名称
pickerLabel.textAlignment=.center
view.addSubview(pickerLabel)
返回视图
}
}
协议时间值UnsecondsDelegate{
func getSecondsValue(从时间:time)
}

您必须从带有
行的数组中获取项目
索引

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    let time = timePickerArray[row]
    delegate?.getSecondsValue(from: time)
}
并声明
getSecondsValue

func getSecondsValue(from time : String) {
  let timeInSeconds = selectedTimes[time] 
}

编辑:

使用结构而不是元组

struct Time {
   let name : String
   let amount : Double
}

...

let selectedTimes = [Time(name:"3 MIN", amount:180.0), 
                     Time(name:"5 MIN", amount:300.0), 
                     Time(name:"10 MIN", amount:600.0), 
                     Time(name:"15 MIN", amount:900.0)]

...

func getSecondsValue(from time : Time) {
   let timeAmountValue = time.amount
}

...

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    let time = selectedTimes[row]
    delegate?.getSecondsValue(from: time)
}

...

pickerLabel.text = selectedTimes[row].name

如果要获取所有值,可以使用
selectedTimes.values
?您正试图用数组为字典下标,但它不起作用,您只能用键值下标,在您的情况下,它应该是字符串谢谢。我取出数组,并尝试将字典直接与selectedTimes[row].timeName而不是timePickerArray一起使用。我已经用我的更改和你的建议更新了我的代码。现在我得到了一个错误,上面写着“不能下标一个值”