Please note, this blog entry is from a previous course. You might want to check out the current one.
Add a C button that clears everything (your display, the new UILabel you added above, etc.). The Calculator should be in the same state as it is at application startup after you touch this new button.
Add an additional row of buttons, one with the label “C” and the rest without labels. It is easiest to remove all autolayout constraints and rebuild them similar to the lecture.
Connect create a new action for the clear method. In there, reset the calculator brain and the display value:
@IBAction func clear() { brain = CalculatorBrain() displayValue = 0 }
Testing the calculator I found an additional problem – perhaps we will have to remove it in future tasks anyway. Up to now it was possible to enter numbers with leading zeros (e.g. “0000” or “0123”).
To prevent this, we need to disallow the entry of another zero, if there is already one – and only one – on screen. If there is a Zero on screen which is followed by a number, remove the leading zero:
@IBAction func appendDigit(sender: UIButton) { ... if userIsInTheMiddleOfTypingANumber { ... if (digit == "0") && (display.text == "0") { return } if (digit != ".") && (display.text == "0") { display.text = digit } else { display.text = display.text! + digit } } else ... }
The complete code for the task #5 is available on GitHub.
I suggest:
// ViewController.swift
@IBAction func clear() {
brain.ClearOpStack()
history.text = “0”
display.text = “0”
}
// CalculatorBrain.swift
func ClearOpStack() {
opStack = []
}
It may not be necessary to initialize history.text as it is done automatically in:
var displayValue: Double {
set {
history.text = brain.showTrack()
}
}
I didn’t like that my Clear button was leaving me with a double, “0.0”, in the display instead of “0” as it shows on startup. Walked through it and realized the set in displayValue was at fault.
Couldn’t find a way to reset or reinit ViewController so I decided to redo displayValue (it was really annoying me).
By changing it to an optional (var displayValue: Double?) I can pass it nil and check for that when I want a reset. Which makes a certain degree of sense to me.
Had to update “displayValue = 0” to “displayValue = nil” in a couple of extra places (my clear function, and the operate and enter funcs). Then I had to fix the non nil case that I had just broken — it was showing “Optional[#]”. Which was as easy as unwrapping my newValue when setting display.text.
var displayValue: Double? {
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set {
if (newValue == nil) {
display.text = “0”
} else {
display.text = “\(newValue!)”
}
userIsInTheMiddleOfTypingANumber = false
paperTape.text! = brain.brainDump()! //my history implementation
}
}
Guess I could have just gone with a clear func that did brain = CalculatorBrain() , display.text = “0”, userIsInTheMiddleOfTypingANumber = false, but I like this solution better.
Not done testing, but so far so good.
Instead of making displayValue an optional Double, how about adding a single line if condition in setter like this:
set{
display.text = (newValue != 0) ? “\(newValue)” : “0”
history.text = brain.showHistory()
}
What do you think?
After all the whole point is to just avoid 0.0 and display 0 instead.
In the solution by the author of the blog, history becomes nil and the label disappears, which isn’t strictly how it was at the startup.
This could be solved by adding a single line if condition to showHistory() or whatever the author named that function
Also displayValue would become 0.0 but at the outset it was 0
I don’t know if author’s displayValue set contained userInTheMiddleOfTypingANumber = false but that is also necessary else numbers such as 0654 would be entered when the user enters 654 upon clearing.
I hope I am on the right track. Please make me aware if I may be wrong. Thanks for this blog!
Also can the author explain if it is wise to initialise entire new CalculatorBrain() instead of creating a reset() function in the CalculatorBrain.swift. I suppose latter would reduce the number of operations
In appendDigit method, I used NSNumberFormater to validate the new display which works quite well.
if let _ = NSNumberFormatter().numberFromString(newValue) {
display.text = display.text! + sender.currentTitle!
}
func resetDisplay() {
display.text = “0”
history.text = “”
}
to avoid 0.0