I'm currently learning Swift by following the Stanford developing iOS app 2015 lecture series. I have completed assignment 1 but am wondering if there is any improvement can be made to my code.
Also, I have not been able to complete extra credit no. 4, so I would appreciate if someone could offer me a hint.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var display: UILabel!
@IBOutlet weak var history: UILabel!
var userIsInTheMiddleOfTyping = false
@IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if digit == "." && display.text!.rangeOfString(".") != nil {
return
}
if userIsInTheMiddleOfTyping {
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTyping = true
}
}
@IBAction func operate(sender: UIButton) {
if userIsInTheMiddleOfTyping {
enter()
}
let symbol = sender.currentTitle!
appendToEntryRecord(symbol)
appendToEntryRecord(" = ")
switch symbol {
case "×": performOperation {$0 * $1}
case "÷": performOperation { $1 / $0}
case "+": performOperation {$0 + $1}
case "−": performOperation {$1 - $0}
case "√": performOperation {sqrt($0)}
case "sin": performOperation {sin($0)}
case "cos": performOperation {cos($0)}
case "tan": performOperation {tan($0)}
case "π": performOperation {M_PI}
default: break
}
}
func performOperation(operation: (Double, Double) -> Double){
if operandStack.count >= 2 {
displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
enter()
}
}
@nonobjc
func performOperation(operation: (Double) -> Double){
if operandStack.count >= 1{
displayValue = operation(operandStack.removeLast())
enter()
}
}
@nonobjc
func performOperation(operation: () -> Double){
displayValue = operation()
enter()
}
var operandStack = [Double]()
@IBAction func enter() {
userIsInTheMiddleOfTyping = false
appendToEntryRecord("\(displayValue)")
operandStack.append(displayValue)
print("operandStack = \(operandStack)")
}
var displayValue: Double {
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set {
display.text = "\(newValue)"
userIsInTheMiddleOfTyping = false
}
}
func appendToEntryRecord(value: String){
history.text = history.text! + " " + value
}
@IBAction func clear() {
display.text = "0"
history.text = "0"
operandStack = [Double]()
}
@IBAction func backspace() {
if display.text!.characters.count > 0 {
display.text = String(display.text!.characters.dropLast())
}
}
@IBAction func changeSign() {
if userIsInTheMiddleOfTyping {
display.text = "-\(display.text!)"
} else {
performOperation {-$0}
}
}
}
@IBAction
in code. If the code run in an@IBAction
method needs to also be called from elsewhere, it should be refactored into another method that's not an@IBAction
. But you need to drastically rethink the way you're handling optionals. \$\endgroup\$@IBAction
manually? I agree that you could put the relevant code in another function, but is there really a point of doing that if you can just call the@IBAction
directly? \$\endgroup\$@IBAction
directly. It's a button handle, it should handle the tap of a button and nothing more. \$\endgroup\$