The timer works but the txtTimer (textfield) in controller doesn't get updated. println outputs correctly but the view doesn't.
计时器可以工作,但是控制器中的txtTimer (textfield)不会被更新。println输出正确,但视图不正确。
How do I reference txtTimer in controller to the txtTimer in Timer class?
如何将控制器中的txtTimer引用到Timer类中的txtTimer ?
FirstViewController:
FirstViewController:
import UIKit
var timer = Timer()
class FirstViewController: UIViewController {
@IBOutlet weak var txtTimer: UILabel! = timer.txtTimer
@IBOutlet var btnStop: UIButton!
@IBOutlet var btnStart: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Events
@IBAction func btnStartTimer_Click(sender: UIButton) {
if (!timer.isRunning()) {
timer.start()
sender.setTitle("Pause", forState: UIControlState.Normal)
self.btnStop.setTitle("Stop", forState: UIControlState.Normal)
self.btnStop.hidden = false
}
else {
timer.pause()
sender.setTitle("Start", forState: UIControlState.Normal)
}
}
@IBAction func btnStopTimer_Click(sender: UIButton) {
sender.hidden = true
timer.stop()
btnStart.setTitle("Start", forState: UIControlState.Normal)
btnStop.setTitle("Stop", forState: UIControlState.Normal)
}
}
Timer:
定时器:
import UIKit
class Timer:NSObject {
var timer: NSTimer = NSTimer()
var time: Int
var state: UInt8
var running: Bool
var txtTimer: UILabel = UILabel()
override init() {
self.time = 0
self.state = 0
self.running = false
}
func destroyInterval() -> Timer {
self.timer.invalidate()
// self.timer = nil
return self
}
func getFormattedTime() -> String {
if self.getState() == 0 { return "00:00:00" }
var hours = Int(self.time / 3600)
var minutes = Int(self.time / 60)
var seconds = Int(self.time % 60)
// Add leading zeros
var strHours: String = hours > 9 ? String(hours) : "0" + String(hours)
var strMinutes: String = minutes > 9 ? String(minutes) : "0" + String(minutes)
var strSeconds: String = seconds > 9 ? String(seconds) : "0" + String(seconds)
return strHours + ":" + strMinutes + ":" + strSeconds
}
func getState() -> UInt8 {
return self.state
}
func getStateText() -> String {
switch(self.state) {
case 0:
return "stopped"
case 1:
return "running"
case 2:
return "paused"
default:
return "404"
}
}
func getTime() -> Int {
return self.time
}
func incrementTime() -> Timer {
self.time++
return self
}
func isRunning() -> Bool {
return self.running
}
func pause() -> Timer {
self.setRunning(false)
.setState(2)
.destroyInterval()
return self
}
private func setRunning(status: Bool) -> Timer {
self.running = status
return self
}
func setState(state: UInt8) -> Timer {
self.state = state
return self
}
func setTxtTimer() -> Timer {
self.txtTimer.text = self.getFormattedTime()
return self
}
func start() -> Timer {
self.setRunning(true)
.setState(1)
self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
return self
}
func stop() -> Timer {
self.setRunning(false)
.setState(0)
.destroyInterval()
.setTxtTimer()
return self
}
func update() -> Timer {
println(self.getFormattedTime())
self.incrementTime()
.setTxtTimer()
return self
}
}
1 个解决方案
#1
1
It would be best to put the timer in the same class with the label to be updated. Here is an example at github by Rex Fatahi:
最好将定时器放在与标签相同的类中进行更新。下面是Rex Fatahi在github上的一个例子:
https://github.com/aug2uag/SwiftTimer/blob/master/TimerApplication/ViewController.swift
https://github.com/aug2uag/SwiftTimer/blob/master/TimerApplication/ViewController.swift
import UIKit
class ViewController: UIViewController {
// timerApplicationLabel
// timerLabel
// startButton
// stopResetButton
var timeInMilliseconds:Float = 0.000;
var stopButtonTitleVariable: NSString = "Stop"
var isPaused: Bool = false
var timerStarted = false
let titleLabelRect = CGRectMake(10, 60, UIScreen.mainScreen().bounds.size.width - 20, 44)
let timerLabelRect = CGRectMake(UIScreen.mainScreen().bounds.size.width/2 - 110, 120, 220, 44)
let startButtonRect = CGRectMake(UIScreen.mainScreen().bounds.size.width/2 - 120, 200, 100, 44)
let stopButtonRect = CGRectMake(UIScreen.mainScreen().bounds.size.width/2 + 20, 200, 100, 44)
let titleLabel: UILabel = {
let label = UILabel()
label.font = UIFont(name:"Helvetica", size:16)
return label
}()
var timerLabel: UILabel = {
let label = UILabel()
label.font = UIFont(name:"Helvetica", size:44)
return label
}()
var startButton: UIButton = {
let button = UIButton()
return button
}()
var stopButton: UIButton = {
let button = UIButton()
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
titleLabel.frame = titleLabelRect
timerLabel.frame = timerLabelRect
titleLabel.text = "Super Awesome Timer Application"
timerLabel.text = "0.000"
self.view.addSubview(titleLabel)
self.view.addSubview(timerLabel)
startButton.frame = startButtonRect
startButton.setTitle("Start", forState: UIControlState.Normal)
startButton.addTarget(self, action: "startTimer", forControlEvents: UIControlEvents.TouchUpInside)
startButton.backgroundColor = UIColor.blueColor()
self.view.addSubview(startButton)
stopButton.frame = stopButtonRect
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
stopButton.addTarget(self, action: "stopTimer", forControlEvents: UIControlEvents.TouchUpInside)
stopButton.backgroundColor = UIColor.blueColor()
self.view.addSubview(stopButton)
}
func startTimer() {
isPaused = false
stopButtonTitleVariable = "Stop"
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
if (!timerStarted){
NSTimer.scheduledTimerWithTimeInterval(0.001, target: self, selector: "updateTimerLabel", userInfo: nil, repeats: true)
timerStarted = true
}
}
func stopTimer() {
// provide the option to reset timer
isPaused = true
switch (stopButtonTitleVariable) {
case "Stop":
if (timeInMilliseconds > 0.000) {
stopButtonTitleVariable = "Reset"
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
}
break
case "Reset":
timerLabel.text = "0.000"
timeInMilliseconds = 0.000
stopButtonTitleVariable = "Stop"
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
default:
break
}
}
func updateTimerLabel() {
// has it been stopped?
if (!isPaused) {
timeInMilliseconds += 0.001
timerLabel.text = NSString(format:"%.3f", timeInMilliseconds)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
#1
1
It would be best to put the timer in the same class with the label to be updated. Here is an example at github by Rex Fatahi:
最好将定时器放在与标签相同的类中进行更新。下面是Rex Fatahi在github上的一个例子:
https://github.com/aug2uag/SwiftTimer/blob/master/TimerApplication/ViewController.swift
https://github.com/aug2uag/SwiftTimer/blob/master/TimerApplication/ViewController.swift
import UIKit
class ViewController: UIViewController {
// timerApplicationLabel
// timerLabel
// startButton
// stopResetButton
var timeInMilliseconds:Float = 0.000;
var stopButtonTitleVariable: NSString = "Stop"
var isPaused: Bool = false
var timerStarted = false
let titleLabelRect = CGRectMake(10, 60, UIScreen.mainScreen().bounds.size.width - 20, 44)
let timerLabelRect = CGRectMake(UIScreen.mainScreen().bounds.size.width/2 - 110, 120, 220, 44)
let startButtonRect = CGRectMake(UIScreen.mainScreen().bounds.size.width/2 - 120, 200, 100, 44)
let stopButtonRect = CGRectMake(UIScreen.mainScreen().bounds.size.width/2 + 20, 200, 100, 44)
let titleLabel: UILabel = {
let label = UILabel()
label.font = UIFont(name:"Helvetica", size:16)
return label
}()
var timerLabel: UILabel = {
let label = UILabel()
label.font = UIFont(name:"Helvetica", size:44)
return label
}()
var startButton: UIButton = {
let button = UIButton()
return button
}()
var stopButton: UIButton = {
let button = UIButton()
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
titleLabel.frame = titleLabelRect
timerLabel.frame = timerLabelRect
titleLabel.text = "Super Awesome Timer Application"
timerLabel.text = "0.000"
self.view.addSubview(titleLabel)
self.view.addSubview(timerLabel)
startButton.frame = startButtonRect
startButton.setTitle("Start", forState: UIControlState.Normal)
startButton.addTarget(self, action: "startTimer", forControlEvents: UIControlEvents.TouchUpInside)
startButton.backgroundColor = UIColor.blueColor()
self.view.addSubview(startButton)
stopButton.frame = stopButtonRect
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
stopButton.addTarget(self, action: "stopTimer", forControlEvents: UIControlEvents.TouchUpInside)
stopButton.backgroundColor = UIColor.blueColor()
self.view.addSubview(stopButton)
}
func startTimer() {
isPaused = false
stopButtonTitleVariable = "Stop"
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
if (!timerStarted){
NSTimer.scheduledTimerWithTimeInterval(0.001, target: self, selector: "updateTimerLabel", userInfo: nil, repeats: true)
timerStarted = true
}
}
func stopTimer() {
// provide the option to reset timer
isPaused = true
switch (stopButtonTitleVariable) {
case "Stop":
if (timeInMilliseconds > 0.000) {
stopButtonTitleVariable = "Reset"
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
}
break
case "Reset":
timerLabel.text = "0.000"
timeInMilliseconds = 0.000
stopButtonTitleVariable = "Stop"
stopButton.setTitle(stopButtonTitleVariable, forState: UIControlState.Normal)
default:
break
}
}
func updateTimerLabel() {
// has it been stopped?
if (!isPaused) {
timeInMilliseconds += 0.001
timerLabel.text = NSString(format:"%.3f", timeInMilliseconds)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}