如何在Swift 5中创建计算器

预期基础课程“ iOS开发人员”的开始,我们将发布由自由作者撰写的文章。







你好!自Swift 5发布以来已经过去了一年多,它为开发人员带来了很多新东西。在本文中,我想谈谈IOS的移动开发,它的工作方式,所需的功能等等。本文面向刚开始在Swift 5中进行编程的人们



操作系统和硬件要求



为了为任何版本的IOS构建应用程序,一种或另一种方式是,您需要一台运行Mac OS(最好是最新版本)的计算机,否则开发人员工具和Xcode的某些部分可能会开始完全无法预测。对于运行Mac OS的系统的需求,引起了其他开发人员的争议和仇恨,这些开发人员不习惯由于操作系统的原因而受到能力的限制。通常,有几种方法:购买或组装Hackintosh(但是,对于自组装,我想警告您,如果没有持续的驱动程序问题,组装这样的计算机将不容易)。我已经看到将操作系统映像安装到虚拟机中以及将Mac OS滚动到普通笔记本电脑上都没有任何驱动程序问题。但是,这种方法需要您具备一些硬件技能,并且可能会缺乏对Mac OS未来版本的100%支持。



当然,另一种替代方法是从Apple购买计算机。如果您想要一台笔记本电脑,那么您可能知道该怎么做(但是我想立即警告您,Xcode立即占用大约25 GB的空间,如果您将其他模拟器下载到设备上,它很容易占用全部44 GB的空间。 128 GB的大小仅应用于IOS开发,而没有其他任何东西,例如node_modules,Pycharm和Unity缓存,自制软件以及其他对开发人员来说会占用大量磁盘空间的东西。如果要执行其他操作,则至少需要一个磁盘从256 GB或更多)。



开发环境选项



除了使用Swift以及使用Cocoa和CocoaTouch库在Xcode中开发应用程序的或多或少的经典方法外,现在还有很多其他方法可以在几乎不使用Xcode的情况下进行开发(只有不使用Xcode,您才能不再构建应用程序)。有几种技术:



  • Xamarin使用C#编写此平台上的应用程序。使用Xamarin,您可以创建任何本机Android应用程序或IOS应用程序。可以使用Visual Studio完成开发。尽管有这样的优势,但很有可能。需要针对每个平台分别编写一些应用程序片段
  • React Native. React , -. . , - , - . , .
  • Flutter. , Flutter Dart Google. , , . , Flutter — React Native, . Dart, -
  • PhoneGap/Cordova. Nitobi, Adobe. , PhoneGap, Apache Cordova, WebView,
  • Unity. IOS, . , . gamedev.




Apple建议使用Swift编程语言来开发应用程序。 Swift是一种相对较新的编程语言,直到2014年才正式发布。它可用于开发用于Mac OS,IOS,并且也支持Linux(所以如果你有,比如说,不是很具体的Linux,你可以放心地下载并试用的语言,例如,从这个链接)。



Swift本身是一种典型的新一代语言,例如Golang。

最初,该语言被认为是一种比Objective C更易于阅读和抗错误的语言。与此同时,Swift可以在同一项目中同时使用C和ObjectiveC。



我没有尝试描述这种语言(乍看之下是C ++,只是通过一种时髦的自动键入功能将其修改为现代现实),而是邀请读者研究Apple的非常出色的文档,其中详细描述了该语言的工作方式它的语法是什么 英文版可以在这里找到,俄语翻译可以在这里找到在您熟悉Swift语言的基础知识之后,我们可以继续进行今天的工作-使用Xcode创建我们的简单计算器。



创建一个计算器



要创建应用程序,我们需要Xcode,可以从AppStore免费下载Xcode。不要被它的评分吓倒-尽管前五条评论给了1星,但这并不意味着您会感到震惊。也许在编辑时确实没有太快地包含语法和提示-但是总的来说,Xcode给我的印象比同一个Android Studio多了好几倍(尽管也许我只是不知道怎么做)。如果您突然想在Xcode之外尝试开发,并且更喜欢JetBrains产品,则可以尝试AppCode-它支持与Xcode的互操作性,与Swift和Objective C的协作以及许多其他不错的功能。我个人没有尝试过,但是如果您从JetBrains订阅了所有软件-为什么不下载并运行它。



因此,您已经安装了Xcode。现在您可以开始开发了。启动一个新项目,然后选择“单页应用程序”:







之后,系统将提示您输入有关您的应用程序的数据。如果这是您第一次启动Xcode,则需要在此处输入Apple ID。之后,您必须填写有关项目名称(在我们的情况下,仅指计算器)以及公司和应用程序名称的信息。如果您不打算将来发布此应用程序,则可以在此处编写任何内容。我选择了Swift作为语言,并选择了Storyboard作为用户界面。到目前为止,我已经放弃了测试,因为我很棒,因为这里真的没有什么可以测试。







创建应用程序后,您可以转到以下位置的文件Calculator.xcodeproj并调整所有设置(如果您认为合适)。现在,我保留了一切,为Iphone和Ipad开发最新版本的IOS 13.6。原则上,您现在可以排除iPad-我们的界面很可能在它上看起来不太好。但是,我要警告您,如果您突然发布-Apple员工正在测试Iphone的应用程序以进行验证,以便它们至少在Ipad上可以正常工作。但在此之前,您仍然必须在开发人员密钥上花费99美元)。



创建应用程序后,您可以立即调用仿真器以跟踪发生的情况。为此,您只需按CMD + R组合键即可。在左上角,您可以选择运行仿真器的设备,还可以通过电缆连接实际的物理设备并立即对其进行测试)。



有很多方法可以在其中创建界面和小部件,我将使用一个中性的选项-创建一个主支架,将其放置在整个屏幕上,然后以编程方式开始定位我的小部件。因此,首先我们转到文件Main.storyboard,将主视图设为黑色,以便更方便地放置元素:







之后,我们将添加一个View,我们将主要使用该View。为此,请单击右上角的加号,通过它可以添加小部件并添加新的小部件,在搜索中键入uiview







之后,我们将此小部件拖动到主屏幕,需要将其扩展到全屏。为此,我们需要与合作constaint。为此,请单击左下角的图标,该图标看起来有点像Darth Vader的飞船,并在每一侧分配0:







之后,新窗口小部件将展开以适合整个屏幕。接下来,就像上次一样,我们需要将小部件的颜色更改为“清除颜色”,直到现在才变为“清除颜色”,这样它才不会干扰我们,我们可以在其中放置小部件。



现在您可以转到文件ViewController.swift,我们将在其中进行所有其余的编程。首先,我们需要使用特殊的标记@IBOutlet,以便能够将Storyboard链接到我们的代码。为此,我们必须编写以下行:



@IBOutlet var holder: UIView!


现在我们可以将代码链接到小部件。为此,实际上,您需要将我们的支架与支架连接。为此,右键单击viewController并将Holder拖到我们的屏幕上:







最后,我们已完成将代码链接到Storyboard的工作,然后可以开始编程了。



接下来,我们将添加两个变量,第一个变量只是可以写入第一个值的数字,第二个变量将是结果值。第三个变量将更加具体,因为我们将使用一个可选的声明(您可以阅读它是哪种动物,您可以在此处阅读更多内容)。可选,可以包含任何值或nil。可选还确保明确处理nil值。另外,我们将从一开始就添加计算器支持的数学运算的列表:



    var firstNumber = 0
    var resultNumber = 0
    var currentOperations: Operation?
        enum Operation {
        case add, subtract, multiply, divide
    }


接下来,我们必须创建一个Label,在其中将显示数字和计算结果。默认情况下,将有0和相当大的字体。我认为其他所有内容都非常清楚:



    private var resultLabel: UILabel = {
        let label = UILabel()
        label.text = "0"
        label.textColor = .white
        label.textAlignment = .right
        label.font = UIFont(name: "Helvetica", size: 100)
        return label
    }()



之后,跳过调用渲染的内置方法(我正在谈论viewDidLoad),我们需要调用一个方法,该方法将调用一个函数,该函数将渲染处理程序函数将挂起的所有按钮。



    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        setupNumberPad() //,      
    }


之后,我们有了函数setupNumberPad首先,我将为字体大小设置一个常量,以便以后(如果有的话)可以立即在应用程序中增大/减小字体大小,因为我无需使用布局。之后,我将创建一个按钮大小-它的宽度将等于我们应用程序屏幕大小的四分之一。



    private func setupNumberPad() {
        let FontSize:CGFloat = 25 
        //      
        let buttonSize: CGFloat = view.frame.size.width / 4 
        //    1/4
        let zeroButton = UIButton(frame: CGRect(x: 0, y: holder.frame.size.height-buttonSize, width: buttonSize*3, height: buttonSize))
        //  UIButton     
        zeroButton.setTitleColor(.black, for: .normal) 
        //    
        zeroButton.backgroundColor = .white
        //   
        zeroButton.setTitle("0", for: .normal) 
        //    0
        zeroButton.titleLabel?.font = UIFont(name: "Helvetica", size: FontSize)
        // , family    
        zeroButton.tag = 1 
        //         
        holder.addSubview(zeroButton)  //    holder 
        zeroButton.addTarget(self, action: #selector(zeroTapped), for: .touchUpInside) 
        //       
 


0占据了屏幕的三分之一,因此我们可以转到右侧的数学操作数列。接下来,我们需要以某种方式呈现所有按钮。当然,可以一一画出它们,但是结果却是又长又沉闷。因为 我们只有一系列从1到9的数字,那么使用循环的决定就很表面了。我将在第一个周期中给出评论,并且 其他两个本质上是重复,我只给他们剪下:



        for x in 0..<3 {
            let button_row_1 = UIButton(frame: CGRect(x: buttonSize * CGFloat(x), y: holder.frame.size.height-(buttonSize*2), width: buttonSize, height: buttonSize))
            //   x     x
            button_row_1.setTitleColor(.black, for: .normal) //
            button_row_1.backgroundColor = .white // 
            button_row_1.setTitle("\(x+1)", for: .normal) //  
            holder.addSubview(button_row_1) //    
            button_row_1.tag = x+2 // .. 1  ,   2
            button_row_1.addTarget(self, action: #selector(numberPressed(_:)), for: .touchUpInside)
            // 
        }


我们号码的其余代码




       for x in 0..<3 {
            let button_row_2 = UIButton(frame: CGRect(x: buttonSize * CGFloat(x), y: holder.frame.size.height-(buttonSize*3), width: buttonSize, height: buttonSize))
            button_row_2.setTitleColor(.black, for: .normal)
            button_row_2.backgroundColor = .white
            button_row_2.setTitle("\(x+4)", for: .normal)
            button_row_2.addSubview(button_row_2)
            button_row_2.tag = x+5
            button_row_2.addTarget(self, action: #selector(numberPressed(_:)), for: .touchUpInside)
        }
        
        for x in 0..<3 {
            let button_row_3 = UIButton(frame: CGRect(x: buttonSize * CGFloat(x), y: holder.frame.size.height-(buttonSize*4), width: buttonSize, height: buttonSize))
            button_row_3.setTitleColor(.black, for: .normal)
            button_row_3.backgroundColor = .white
            button_row_3.setTitle("\(x+7)", for: .normal)
            holder.addSubview(button_row_3)
            button_row_3.tag = x+8
            button_row_3.addTarget(self, action: #selector(numberPressed(_:)), for: .touchUpInside)
        }
    




此后,我们需要放置CE按钮,将其重置输入的数据。我们将其放在顶部,稍后再描述其功能负载。现在,我们只需要放置它并连接处理程序即可:



        let clearButton = UIButton(frame: CGRect(x: 0, y: holder.frame.size.height-(buttonSize*5), width: view.frame.size.width - buttonSize, height: buttonSize))
        clearButton.setTitleColor(.black, for: .normal)
        clearButton.backgroundColor = .init(red: 0, green: 2, blue: 0.8, alpha: 1) //       rgb
         clearButton.titleLabel?.font = UIFont(name: "Helvetica", size: FontSize-4) //     
        clearButton.setTitle("CE", for: .normal)
        holder.addSubview(clearButton) //     holder
        clearButton.addTarget(self, action: #selector(clearResult), for: .touchUpInside) //  


我们已经完成了无聊的重复部分,现在我们可以做另一件事了—我们可以用来执行数学运算的操作数。首先,我们将必要的操作数放置在数组中,从那里开始。我们将操作数按钮本身放在一列中,并添加一个处理程序函数,该函数将对按下操作数做出反应。我将把按钮做成幼稚的惊喜颜色,黄色,大小比我们的数字大一点。



        let operations = ["=","+", "-", "x", "÷"] //  

        for x in 0..<5 {
            let button_operand = UIButton(frame: CGRect(x: buttonSize * 3, y: holder.frame.size.height-(buttonSize * CGFloat(x+1)), width: buttonSize, height: buttonSize))
            button_operand.setTitleColor(.black, for: .normal)
            button_operand.backgroundColor = .init(red: 2, green: 0.8, blue: 0, alpha: 1) // 
            button_operand.setTitle(operations[x], for: .normal)
            holder.addSubview(button_operand)
            button_operand.tag = x+1 
            // ,       
            button_operand.titleLabel?.font = UIFont(name: "Helvetica", size: FontSize)
            button_operand.addTarget(self, action: #selector(operationPressed(_:)), for: .touchUpInside)
        }


在完成这些全局操作之后,我们只需要放置Label并将结果写入其中,然后关闭函数即可:



    resultLabel.frame = CGRect(x: 20, y: clearButton.frame.origin.y - 110.0, width: view.frame.size.width - 40, height: 100)
    holder.addSubview(resultLabel)
} //    


现在,您可以继续处理程序:



与处理程序一起工作



所有这些基本上只是一个布局,现在我们必须向应用程序中注入逻辑。为此,我们将使用Objective C运行时中的方法来简化代码。如果您不了解发生了什么,我可以推荐这篇文章供阅读。



因此,这是我们的功能:



    @objc func clearResult() {
        resultLabel.text = "0" //    0
        currentOperations = nil //    
        firstNumber = 0 //      0
    }
    
    @objc func zeroTapped() {
        //    
        if resultLabel.text != "0" {
            if let text = resultLabel.text {
                resultLabel.text = "\(text)\(0)" //  
            }
        }
    }


接下来,我们需要向按钮添加处理程序函数:



    @objc func numberPressed(_ sender: UIButton) {
        let tag = sender.tag - 1
        
        if resultLabel.text == "0" {
            resultLabel.text = "\(tag)"
        }
        else if let text = resultLabel.text {
        //   
            resultLabel.text = "\(text)\(tag)"
        }
    }



接下来是我们应用程序中最重要的业务逻辑。我们将使用switch构造来控制我们的数学运算:



 @objc func operationPressed(_ sender: UIButton) {
        let tag = sender.tag
        
        if let text = resultLabel.text, let value = Int(text), firstNumber == 0 {
            //   
            firstNumber = value
            resultLabel.text = "0"
        }
        
        if tag == 1 {
            if let operation = currentOperations {
                var secondNumber = 0
                if let text = resultLabel.text, let value = Int(text) {
                    secondNumber = value
                }
                
                switch operation {
                case .add:
                    
                    firstNumber = firstNumber + secondNumber
                    secondNumber = 0 //  
                    resultLabel.text = "\(firstNumber)" 
                    currentOperations = nil
                    firstNumber = 0 //     Label 
                    
                    break
                    
                case .subtract:
                    firstNumber = firstNumber - secondNumber
                    secondNumber = 0
                    resultLabel.text = "\(firstNumber)"
                    currentOperations = nil
                    firstNumber = 0
                    
                    break
                    
                case .multiply:
                    firstNumber = firstNumber * secondNumber
                    secondNumber = 0
                    resultLabel.text = "\(firstNumber)"
                    currentOperations = nil
                    firstNumber = 0
                    
                    break
                    
                case .divide:
                    firstNumber = firstNumber / secondNumber
                    secondNumber = 0
                    resultLabel.text = "\(firstNumber)"
                    currentOperations = nil
                    firstNumber = 0
                    break
                }
            }
        }
        else if tag == 2 {
            currentOperations = .add 
            //     .    ,    
        }
        else if tag == 3 {
            currentOperations = .subtract
        }
        else if tag == 4 {
            currentOperations = .multiply
        }
        else if tag == 5 {
            currentOperations = .divide
        }
    }
}



就这样!可以在链接中找到此应用程序的源代码结果,结果是这样的:







按照传统,我将提供一些有用的资源,这些资源可能对初学者IOS开发人员有用:








iOS开发快速入门。免费网络研讨会







All Articles