//
// ViewController.swift
// calculator
//
// Created by 郭百度 on 2017/9/23.
// Copyright ? 2017年 Luke. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTyping = false
var lessOnePoint = true
@IBAction func touchDigit(_ sender: UIButton) {
let digit = sender.currentTitle!
//課后修正計算器bug添加,當輸入為"."時判斷,屏幕上數字是否已有小數點,是的話不執行
let point: Character = "."
if digit == String(point) && display.text!.contains(".") {
lessOnePoint = false
}
if lessOnePoint {
if userIsInTheMiddleOfTyping {
let textCurrentlyInDisplay = display.text!
display.text = textCurrentlyInDisplay + digit
print("I'm \(digit) b")
} else {
display.text = digit
userIsInTheMiddleOfTyping = true
print("I'm \(digit) c")
}
}
lessOnePoint = true
}
var displayVaule: Double {
get {
return Double(display.text!)!
}
set {
display.text = String(newValue)
}
}
private var brain = CalculatorBrain()
@IBAction func performOperation(_ sender: UIButton) {
//執行運算按鈕中,如果用戶正在鍵入中,那么將display值提交到brain的蓄存器中,用于實現當用戶點擊開根號等計算時,將屏幕display數進行緩存
if userIsInTheMiddleOfTyping {
brain.setOperand(displayVaule)
}
//標識用戶停止鍵入
userIsInTheMiddleOfTyping = false
//那么讓model執行數學運算符判斷,將輸入值sender標題→mathmaticalSymbol數學符號→brain執行運算函數
if let mathmaticalSymbol = sender.currentTitle {
brain.performOperation(mathmaticalSymbol)
}
//那么讓我們將model中的結果從堆中復制給view中result,在view中將其復制給屏幕(label)
if let result = brain.result {
displayVaule = result
}
}
}
//
// CalculatorBrain.swift
// calculator
//
// Created by 郭百度 on 2017/9/23.
// Copyright ? 2017年 Luke. All rights reserved.
//
import Foundation
//func changeSign(operand: Double) -> Double {
// return -operand
//}
//func multiply(op1:Double, op2:Double) -> Double{
// return op1 * op2
//}
struct CalculatorBrain {
//構建私有變量accumulator雙精度蓄存器
private var accumulator: Double?
private enum Operation {
case constant(Double)
case unaryOperation((Double) -> Double)
case binaryOperation((Double,Double) -> Double)
case equals
}
//生命私有變量operations(加了s)為字典,為字典賦值
private var operations: Dictionary<String,Operation> = [
"π" : Operation.constant(Double.pi),
"e" : Operation.constant(M_E),//M_E,
"√" : Operation.unaryOperation(sqrt),//sqrt,
"cos" : Operation.unaryOperation(cos), //cos
"±" : Operation.unaryOperation({-$0}), //±
"+" : Operation.binaryOperation({ $0 + $1} ), // x *
"-" : Operation.binaryOperation({ $0 - $1 }), // x *
"×" : Operation.binaryOperation({ $0 * $1 }), // x *
"÷" : Operation.binaryOperation({ $0 / $1 }), // x *
"=" : Operation.equals
]
//構建多變函數執行運算,輸入值忽略標簽,變量symbol符號,類型為字符串
mutating func performOperation(_ symbol: String) {
//如果字典查詢operations[symbol]有值的話,將其賦值給變量operation,沒有則跳過整個枚舉
if let operation = operations[symbol] {
//對賦值后的operation進行解析
switch operation {
//聲明字典內提取為“值”value,將字典內常數值直接給蓄存器
case .constant(let value):
accumulator = value
//聲明字典內提取為“函數”function,蓄存器中若不為nil,則進行sqrt、cos等枚舉的函數運算,否則跳過
case .unaryOperation(let function):
if accumulator != nil {
accumulator = function(accumulator!)
}
//聲明字典內提取為“二元函數運算”同樣適用function(不同枚舉不沖突),蓄存器中若不為nil,則進行枚舉binaryOperation字典中的運算公式,運算函數為function,為區別,此處與官方教程不同使用了function2和functionVaule更易懂
case .binaryOperation(let functionVaule):
if accumulator != nil {
pendingBinaryOperation = PendingBinaryOperation(funciton2: functionVaule, firstOperand: accumulator!)
accumulator = nil
}
case .equals:
performPendingBinaryOperation()
}
} else {
//之前一個用x當乘號一個用×當乘號……然后乘法一直沒用……坑
print("沒有找到枚舉值")
}
}
private mutating func performPendingBinaryOperation() {
if pendingBinaryOperation != nil && accumulator != nil {
accumulator = pendingBinaryOperation!.perform(with: accumulator!)
pendingBinaryOperation = nil
}
}
private var pendingBinaryOperation: PendingBinaryOperation?
private struct PendingBinaryOperation {
//此處聲明了二元函數運算中為兩個雙精度變量輸入及一個雙精度變量輸出
let funciton2 : (Double,Double) -> Double
let firstOperand : Double
func perform(with secondOperand:Double) -> Double {
//此處調用了function為枚舉計算公式,在swift中使用$0、$1...按順序輸入變量
return funciton2(firstOperand,secondOperand)
}
}
mutating func setOperand(_ operand:Double) {
accumulator = operand
}
//輸出結果
var result: Double? {
get {
return accumulator
}
}
}
引用
Swift 語言 iOS10 開發 斯坦福(Stanford) CS193p 公開課(1)
Swift 語言 iOS10 開發 斯坦福(Stanford) CS193p 公開課(2)
Swift 語言 iOS10 開發 斯坦福(Stanford) CS193p 公開課(3)