我是一个初学者,因此如果这一切看起来很怪异,我深表歉意。
我有一个“时间和秒数字典”。这是一个带有pickerView
的倒计时计时器应用程序,可让您选择倒计时开始时间,并在pickerView的didSelect
中选择时间后,它将使用该时间量更新timerLabel。然后,当您点击播放时,它将从该时间量开始播放。
我正在尝试使用pickerView的didSelect
中的协议来告诉我何时选择了时间,然后将时间与其以秒为单位的时间量值匹配,将Seconds转换为Hours:Minutes:Seconds并传递该信息发送给计时器,以便可以从该时间开始播放。但是,我无法完成委托。
我收到此错误:当我尝试在协议存根中调用键的值时,无法用类型为[[String]'的索引下标'[String:Int]'的值。我知道基本上我有一个数组,但无法从中获取键的值,但是我需要帮助弄清楚现在如何倒退……从数组返回键和值。我将所有Times都放入了pickerView数组中,但是我对如何获取在我给pickerview的Times数组中选择的键的值感到困惑。
到目前为止,这是我的代码,其中显示错误:
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)
}
答案 0 :(得分:1)
您必须从具有row
索引的数组中获取项目
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