如何将IBOutlet设置为对另一个对象的引用

时间:2022-03-05 14:31:37

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.
    }


}