本文利用ios实现计算器app,后期将用mvc结构重构
import UIKitclass CalculViewController: UIViewController {@IBOutlet weak var display: UILabel!var userIsInTheMiddleOFTypingANumber:Bool=false@IBAction func appendDigit(sender: UIButton) {let digit=sender.currentTitle!if userIsInTheMiddleOFTypingANumber {display.text=display.text!+digit}else{display.text=digituserIsInTheMiddleOFTypingANumber=true}}var operandstack:Array<Double>=Array<Double>()@IBAction func operate(sender: UIButton) {let operation=sender.currentTitle!;if userIsInTheMiddleOFTypingANumber {enter()}switch operation {case "×":performeOperation{$0*$1}case "÷":performeOperation{$1/$0}case "+":performeOperation{$0+$1}case "-":performeOperation{$1-$0}case "√":performeOperation{sqrt($0)}default:break}}// func multiply(op1:Double,op2:Double) -> Double {
// return op1*op2;
// }func performeOperation(operation:(Double,Double)->Double){if operandstack.count>=2 {displayValue=operation(operandstack.removeLast(),operandstack.removeLast())enter()}}private func performeOperation(operation:Double->Double){if operandstack.count>=1 {displayValue=operation(operandstack.removeLast())enter()}}@IBAction func enter() {userIsInTheMiddleOFTypingANumber=falseoperandstack.append(displayValue)print("operandstack=\(operandstack)")}var displayValue:Double{get{return NSNumberFormatter().numberFromString(display.text!)!.doubleValue}set{display.text="\(newValue)"userIsInTheMiddleOFTypingANumber=false}}
知识点如下
- 计算型属性的setter与getter
- swift利用函数作为参数
- swift的重载,详情参见:swift override
效果如下
增加model文件
import Foundationclass CalculatorBrain {private enum Op : CustomStringConvertible{case operand(Double)case UnaryOperation(String,Double->Double)case BinaryOperation(String,(Double,Double)->Double)var description:String{get{switch self {case .operand(let operand):return "\(operand)"case .BinaryOperation(let symbol,_):return symbolcase .UnaryOperation(let symbol, _):return symbol}}}}private var opstack=[Op]()private var knowOps=[String:Op]()init(){func learnOp(op:Op){knowOps[op.description]=op}learnOp(Op.BinaryOperation("×"){$0*$1})learnOp(Op.BinaryOperation("÷"){$1/$0})learnOp(Op.BinaryOperation("+"){$0+$1})learnOp(Op.BinaryOperation("-"){$1-$0})learnOp(Op.UnaryOperation("√"){sqrt($0)})
// knowOps["×"]=Op.BinaryOperation("×"){$0*$1}
// knowOps["÷"]=Op.BinaryOperation("÷"){$1/$0}
// knowOps["+"]=Op.BinaryOperation("+"){$0+$1}
// knowOps["-"]=Op.BinaryOperation("-"){$1-$0}
// knowOps["√"]=Op.UnaryOperation("√"){sqrt($0)}}private func evaluate(ops:[Op])->(result:Double?,remainOps:[Op]){if !ops.isEmpty {var remainOps=ops;let op=remainOps.removeLast()switch op {case Op.operand(let operand):return(operand,remainOps)case Op.UnaryOperation(_, let operation):let operandEvalution=evaluate(remainOps)if let operand=operandEvalution.result{return(operation(operand),operandEvalution.remainOps)}case Op.BinaryOperation(_, let operation):let operandEvlution1=evaluate(remainOps)if let operand1=operandEvlution1.result {let operandEvlution2=evaluate(operandEvlution1.remainOps)if let operand2=operandEvlution2.result {return (operation(operand1,operand2),operandEvlution2.remainOps)}}}}return (nil,ops)}func evaluate()->Double?{let (result,remainder)=evaluate(opstack)print("\(opstack)=\(result)with\(remainder)left over")return result}func pushOperand(operand:Double)->Double?{opstack.append(Op.operand(operand))return evaluate()}func performOperation(symbol:String)->Double?{if let operation=knowOps[symbol]{opstack.append(operation)}return evaluate()}}
controll修改为
import UIKitclass CalculViewController: UIViewController {@IBOutlet weak var display: UILabel!var userIsInTheMiddleOFTypingANumber:Bool=falsevar brain=CalculatorBrain()@IBAction func appendDigit(sender: UIButton) {let digit=sender.currentTitle!if userIsInTheMiddleOFTypingANumber {display.text=display.text!+digit}else{display.text=digituserIsInTheMiddleOFTypingANumber=true}} //var operandstack:Array<Double>=Array<Double>()@IBAction func operate(sender: UIButton) {if userIsInTheMiddleOFTypingANumber {enter()}if let operation=sender.currentTitle{if let result=brain.performOperation(operation) {displayValue=result}else{displayValue=0}}}@IBAction func enter() {userIsInTheMiddleOFTypingANumber=falseif let result=brain.pushOperand(displayValue){displayValue=result}else{displayValue=0}}var displayValue:Double{get{return NSNumberFormatter().numberFromString(display.text!)!.doubleValue}set{display.text="\(newValue)"userIsInTheMiddleOFTypingANumber=false}}}