swift_calculator( 初学心得 )

最后呈现的UI

swift_calculator( 初学心得 )_第1张图片
CE93F82D-C3E4-4C2B-8251-F3BC1703D676.png

mainStoryBoard布局

swift_calculator( 初学心得 )_第2张图片
A2CC459F-CCF1-41B2-B5F1-4ECFA0355244.png
  @IBOutlet weak var display: UILabel!
  @IBAction func appendDigit(sender: UIButton) {}
  @IBAction func operate(sender: UIButton) {}
  @IBAction func enter() {}
  • display

    • var display 表示的是对一个变量的声明,@IBOutlet 意味着是 SB中 拖出的 引用,:表示继承的类别这是从SB(故事版的简称)中脱出的空间已经存在所以 UILable!中的!解包,表示这个实例对象是不能为nil的也就是不可optional。 weak是为了内存安全,不导致重复引用,这个Lb的创建是在SB而我们的控制器只是对他进行引用,所以你可以简单理解为 值传递 这里写出weak防止控件的引用计数器+ 1.
  • appendDigit

    • @IBAction,SB中发送的消息触发事件。 appendDigit ,0...9的Btn事件触发消息。(sender: UIButton) 触发事件的对象。
    • operate 同理 ,加减乘除发送的消息
    • enter。return键 的消息 。我们不关注发送的对象,只是关心事件的执行,省去( )中的参数,SB拖线中type选中 None
var userIsInputNum = false
    
    @IBAction func appendDigit(sender: UIButton) {
        let digit = sender.currentTitle!

        if userIsInputNum {
            display.text = display.text! + digit
        }else{
            display.text = digit
            print("display.text =  \(display.text!)")
            userIsInputNum = true
        }
    }

全局变量的声明在swift中是要赋予初始值的,let 和var 区别,let是一种值传递, userIsInputNum 用户是否正在进行计算操作,如果是第一次操作Lb的text是点击Btn上的数字。如果是正在操作计算则是文本拼接. 例如:6 按击 2次,Lb中显示66. swift中文本的拼接直接写+就行了,OC中却使用[NSString stringWithFormate...],方便吧!

   var openrandStack = Array()
   @IBAction func enter() {
        userIsInputNum = false
        openrandStack.append(displayValue)
        print("openrandStack = \(openrandStack)")
    }
    
    var displayValue : Double{
        get{
            return (NSNumberFormatter().numberFromString(display.text!)!.doubleValue)
        }
        set{
            display.text = "\(newValue)"
            userIsInputNum = false
        }
    }
  • 我们现在应该把计算要的数字存入我们的栈,也就是Array。var #变量名 = #类型<#存放中 遵循的类型> ()#赋予空间 ,每次return进入enter也就是用户的文本拼接结束,将之前Lb中拼接好的文本存入栈中。displayValue重写它的get 、set方法为的是将Lb的text转为Double类型符合规范。
    "\(newValue)"拼接为字符串 同print("display.text = \(display.text!)"),newValue 是在执行set方法时,传入的值

运算 ,我说下逻辑,用户可能在点击6 再去retrun,也可能是去点击 加减乘除的运算符,这个时候的效果都应该是存入栈,点击运算符只有当栈中的个数多于等于2 的时候才会执行。set的赋值在结束的一刻其实调用了get(希望大家明白)

@IBAction func operate(sender: UIButton) {
        let operation = sender.currentTitle!
        if userIsInputNum{
            enter()
        }
        switch operation{
            case "×" : performOperation{ $0 * $1 }
            case "÷" : performOperation{ $1 / $0 }
            case "−" : performOperation{ $1 - $0 }
            case "+" : performOperation{ $0 + $1 }
            case "√" : performOperation{ sqrt($0) }
            default  : break
        
        }
    }

    func performOperation(operation : (Double , Double) -> Double){
        if openrandStack.count >= 2{
            displayValue = operation(openrandStack.removeLast(),openrandStack.removeLast())
            print("displayValue =  \(displayValue)")
            enter()
        }
    
    
    }
   
    private func performOperation(operation : Double -> Double){
        if openrandStack.count >= 1{
            displayValue = operation(openrandStack.removeLast())
            enter()
        }

        
    }

performOperation { $0 * $1 }

performOperation({(po1 : Double , po2 : Double) -> Double in return po1 * pop })

因为swift编译的时候对变量名没有要求,而且performOperation中有函数指针的参数类型,没有声明的变量名用$0...$n表示,所以可以写成

performOperation({($0 * $1)})

而因为最后一个形参可以写在外部,并且无参()可以省略 -----> performOperation { $0 * $1 }

  • 算数平方根的求取,利用重载 方法,通过形参的个数让编译器自行判断发送消息的对象。
    • swift 中,控制器 的父类是UIViewController 而它 的父类 NSObject相当于导入了OC。因为oc中 重载的时候会报同名错误。所以在switf中加上private 私有化 区别。
AutoLayout
swift_calculator( 初学心得 )_第3张图片
2C877D15-30D8-4D38-B362-A9A716210726.png

这是有规律的约束一起设置的方法。注意我除了按键其他的都是空白的按钮填充 ,使最后成为了5 * 4 的一个矩阵。然后选中所有的空间选中红箭头设置but 的 W 和 H,eaqul(相等)并且距离上(Lb),左右下(控制器 view边界)一个固定值。试试吧 小伙子

github源代码

  • 代码下载地址 : calculator

有问题反馈

在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

你可能感兴趣的:(swift_calculator( 初学心得 ))