best practices - when to check condition before updating UI?

I'd lke to hear peoples comments on what the best practices would be for the need to checking a condition before updating a User Interface element in iOS (including watchOS and tvOS).


Here are some examples *


1. An Undo button keeping track of changes


func update(_ data: Data) {
     updateHistory(data: Data)
     if !btnUndo.isEnabled { btnUndo.isEnabled = true } // use this one or
     btnUndo.isEnabled = true // use this one?
}


2. Text in a label that hasn't changed


var timerMonitorHeartRate = Timer()

func startMonitoring() {
     timerMonitorHeartRate.invalidate()
     timerMonitorHeartRate = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] timer in
          self?.displayHeartRate()
     }
}

func displayHeartRate() {
     let heartRateValue  = BLEHeartRate.value // value comes from some async function
     let heartRateString = String(format: "Heart Rate %1.2f", heartRateValue)
     if (lblHearRate.text != heartRateString) { lblHearRate.text = heartRateString } // use this one or
     lblHearRate.text = heartRateString // use this one?
}

* these exmples are just off the top of my head, I didn't check them for syntax, only to give you an idea of what I'm talking about.


Should we check the conditon before updating an item or does the underlaying code do that for us (i.e., the button will not actually undergo a paint refresh since it will internally check and already know that it is enabled). If this is the case, would the same thing happen when updating a text property with the same text?

Replies

There are things you don't control.


When you hit a button, its state may change before you start the IBAction.


It is up to you to restore the stae if you cancel the action.


There is limited interest in doing the test:

if (lblHearRate.text != heartRateString) { lblHearRate.text = heartRateString } // use this one or


If text is different, it is equivalent to doing directly

lblHearRate.text = heartRateString


And if it is the same, it will remain the same, without any visual effect.


And testing may be as resource consuming as allocating ; anyway, there is no performance issue there.

Under MVC (model-view-controller) you never use a 'view' element like a button or a textfield to describe the state of the app. You use a variable in 'model' to describe the state and you set that value in the 'view' as determined by the 'controller'. This allows you to change the display elements without reprogramming everything. It also allows you to move an app from an iPhone to an iPad or, God forbid, an Android. They all have somewhat different 'view' elements. If the logic is in the 'model' that makes the switch pretty easy. Also - switching from portrait to landscape - you no longer might have that button or textfield. And in the next revision you might switch from textfields to......

thanks