简体   繁体   中英

UILabel unexpectedly returns nil

Making a basic stopwatch. My model is updating my controller fine but when I attempt to update my UILabel it's returning nil .

It's only returning nil when I'm attempting to update from the timer. If I update the controller without using the timer, it will update the label.

I think I must be missing something.

View Controller:

class ViewController: UIViewController {
    var stopWatchBrainInstance = stopWatchBrain()
    //Outlets
    @IBOutlet weak var timerLabel: UILabel!

    var displayValue:Int{
        get{
            print("getting Display Val")
            return Int(timerLabel.text!)!
        }
        set{
            timerLabel?.text! = String(val)
        }
    }

    @IBAction func buttonPressed(_ sender: UIButton) {
        if let buttonId = sender.currentTitle{
            let testVAr = displayValue

            stopWatchBrainInstance.setButton(pressed: buttonId, currentDisplayVal: testVAr)
            displayValue = stopWatchBrainInstance.timerVal
        }
    }
}

Model:

class stopWatchBrain:NSObject {
    //Public API

    public  func setButton(pressed identifier:String,currentDisplayVal:Int){
        switch identifier{
        case "Start":
            startTimer(currentTime: currentDisplayVal)
            break
        case "Stop":
           stopTimer()
        default:
            break
        }
    }

    public var timerVal: Int {
        get{
            return stopwatchValue
        }
    }

    //Vars
    private var timer = Timer()
    private var stopwatchValue:Int = 1

    //Methods
    private  func startTimer (currentTime: Int){
        timer = Timer.scheduledTimer(timeInterval: 1, target: self,   selector: (#selector(self.runtheTimer)) , userInfo: nil, repeats: true)
    }

    private  func stopTimer (){
        print("stopping timer")
        timer.invalidate()
    }

    @objc private func runtheTimer(){
        stopwatchValue += 1
        print(stopwatchValue)

        ViewController().setTitle(stopwatchValue)
    }
}

The problem is this line:

ViewController().setTitle(stopwatchValue)

Do you know what it does? It makes a completely new and separate ViewController object (not the one in the interface), calls its setTitle method, and throws it away.

Matt gave you the main flaw with your code, although there are some other messes to clean up as well.

As for how your StopWatchBrain would call your view controller, this would be a good use case for the delegate design pattern. Read up on that. You'd give your StopWatchBrain class a delegate that it would call when the value changes.

You'd make the view controller the delegate of the StopWatchBrain and it would update it's label when it's delegate method gets called with a new timer value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM