Learn HTML & CSS Learn HTML & CSS
Only this week 80 % discount on HTML & CSS and JavaScript e-learning courses!

Lesson 4 - Simple iOS calculator in Swift

In the previous lesson, Swift UI for different screen sizes and Autolayout, we tried to position components using Autolayout. It was still rather an introductory lesson. In today's iOS tutorial, we'll finally get to programming! Let me reveal it'll be a simple calculator.

Before we start with the calculator itself, let's have a look at how to connect our UI (the individual components) to Swift code so we can work with them and, for example, react to a button being clicked.

Connecting the UI and code

To be able to change any component or get their state or data at runtime, we have to connect them to the application logic. Assistant Editor which we introduced in the last lesson will be useful for that.

First, make sure you have the Main.storyboard file opened. You can switch between editors in the top right corner - the icon of two overlapping circles. When clicked, two editor windows will show up. The first one, on the left, displaying the main storyboard and the second displaying the ViewController.swift file. This very file is connected to our controller. Everything is already set in the project. We'll learn to create new controllers, resulting in multiple screens, in further lessons. If the right side editor isn't displaying the correct swift file, you can select one manually in the navigation right above the editor. Choose Manual instead of Automatic and click through the file.

Now we can finally start connecting the UI to the code. Select Label we added in the beginning of the course and while holding Ctrl, hold the left mouse button and move the cursor to the editor with Swift code. A blue line and the "Insert Outlet or Outlet Collection" text will show up. Now release the mouse button and the dialog below will pop up:

Instead of Ctrl + the left mouse button, you can also right-click and drag without holding Ctrl.

All we have to do now is to enter the name of our component in the dialog, e.g. myLabel, and confirm by pressing "Connect":

Connecting Label with code in Xcode

Congratulations! You've just successfully connected a component to the code and now your Label is ready to be modified. There's the viewDidLoad() method prepared in the controller which is called after initializing the UI controller. Here you can try to modify your Label. For example, let's change its text and color:

override func viewDidLoad() {
        super.viewDidLoad()

        myLabel.text = "Hello from Code!"
        myLabel.textColor = UIColor.red
}

Right after the component is connected and @IBOutlet is created in the code, we have to be careful about deleting this reference (the particular code line). For example, we if change our mind and won't want to modify the Label anymore, we could delete the code line. However, if we do that, we also have to delete the connection we've created. Otherwise, the application crashes when loading the controller and the error message won't be much of a help.

To delete the connection, just right-click the Label either directly in the UI or in the list in the right column and delete the connection in the Referencing outlets section.

Deleting outlets in Xcode

Reacting to button clicks and other events

@IBOutlet isn't the only way to connect the UI to the code. The second is @IBAction which reacts to user actions. The best example would be a button, let's have a look at how to connect one to the code. Add a new Button into the controller and if you haven't opened the Assistant Editor yet, do it now. The procedure is basically the same as with the Label above.

As soon as you drop the button into the code, an Outlet dialog pops up. First, select Action in the Connection menu. Then we just fill in the name (of the method that is going to be created). I personally always change the Type from Any to the control type I'm connecting, in this case UIButton. Click the "Connect" button and that's it. Your new method will be executed every time the button is clicked. I personally also suffix the button methods as Btn_Click, so this example method could be named as testBtn_Click.

Connecting a handling method to a Button in Xcode

Creating a simple calculator

To try out the new stuff, let's make a trivial calculator. Create a new Simple View App project. I chose SimpleCalculator_ICTsocial as the project name.

Designing the UI

Now it's necessary to think about what we'll need in our calculator. We want to perform operations with two numbers, which would mean two Text Field components, and also a Button to perform the calculation.

It's also a good idea provide a smart way for selecting math operations - addition, subtraction, multiplication, and division. The PickerView component will be perfect for this. Place the components into the prepared View Controller. The best would be if you placed them in the upper part, since when entering numbers, a keyboard will be shown in the bottom part. The result will look like this:

Text Fields and PickerView in Xcode

I set the controller background to blue to make the TextField components more visible. To avoid setting the constraints to all the components, we'll use StackView.

StackView

The StackView component makes it easy to stack components next or under each other, without setting their constraints. You specify the Alignment (either centered or via constraints) to this component only.

Except the Axis property, which determines the direction of the components (vertical, horizontal), you'll also often use Alignment, Distribution, and Spacing. The first one set alignments, the second one determines how components of different sizes will behave, and the third defines the spacing between components. Try to place several components into the StackView and test the properties out.

The simplest way to place the components into the StackView is by selecting them and clicking the Embed in Stack option in the constraints menu we've already been using. The components may be a little misplaced, but you can just play with this in the StackView settings. We can also drop the StackView from the component library (it's named Vertical Stack View and Horizontal Stack View, but we can change this orientation later) and choose the direction right away. Let's place the components into the StackView.

Select all the components we added (by dragging the mouse or Cmd + left mouse button in the list on the left) and click the Embed in Stack button in the menu where we've been setting the constraints. This way, Xcode basically creates a new Stack View and places all the selected components inside. Chores made easy. The result is the same as if we'd drop the Stack View from the library and place all the components inside manually.

StackView when designing a calculator in Xcode

The result:

StackView when designing a calculator in Xcode

The components will be probably misplaced. Don't panic. First, let's set the constraints of our new StackView to 0 from the top, bottom, left, and right edge.

Then we'll set constraints to our TextField components, you can select both of them by holding Cmd. We'll set the left and right constraints to e.g. 10. Let's also add some text to the button, e.g. "Calculate". I also changed the font color to white because of the blue background. We can set the Spacing property of our Stack View to avoid having our components to close to each other.

The user interface should look something like this:

Completed user interface of the iOS calculator in Xcode

A last detail. In Attributes inspector, let's set the Keyboard Type attribute of our TextFields to Number Pad. This attribute can be found in the Text Input Traits category. This way, the keyboard changes to a number pad when entering numbers.

In Xcode, you can switch between individual device views and see that the UI is responsive towards it.

Responsive UI in Xcode

Code

We've finished the user interface, let's move to the code. Open the Assistant Editor in Xcode and create outlets for our TextField components and for the PickerView. Also create an action for the button click:

@IBOutlet weak var firstNumberInput: UITextField!

@IBOutlet weak var secondNumberInput: UITextField!

@IBOutlet weak var mathOperationPicker: UIPickerView!

@IBAction func calculateBtnClick(_ sender: Any) {

}

A simple action won't be enough for the PickerView, instead, we have to set our controller as a data source and delegate. We are provided with two protocols for that, let's add them:

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

Then we just have to set these attributes in the viewDidLoad() method using self:

override func viewDidLoad() {
        super.viewDidLoad()
    mathOperationPicker.dataSource = self
        mathOperationPicker.delegate = self
}

We're basically telling the PickerView that our controller will take care of the data and handle the component by itself.

We can't build the app now, we still have to implement two methods. Xcode will help us by generating them:

func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 4
}

Because we know how many components and rows we'll have, we can "hard-code" the numbers. The last method remaining isn't necessary for a correct build. We'll set what should the PickerView display:

let mathOperations = ["+", "-", "*", "/"]

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return mathOperations[row]
}

We can try to run the app to make sure everything works fine. Design isn't the best (it's horrible, actually), but that's not the point of today's tutorial:

Now let's implement the action of the "Calculate" button:

@IBAction func calculateBtnClick(_ sender: Any) {
        let firstNumber = Int(firstNumberInput.text!)!
        let secondNumber = Int(secondNumberInput.text!)!

        let selectedMathOperation = mathOperationPicker.selectedRow(inComponent: 0)
        var result : Int

        switch selectedMathOperation {
        case 0:
            result = firstNumber + secondNumber
        case 1:
            result = firstNumber - secondNumber
        case 2:
            result = firstNumber * secondNumber
        case 3:
            result = firstNumber / secondNumber
        default:
            result = 0
        }
        displayMessage(message: String(result))
}

Finally, we'll implement the displayMessage() method displaying the result in a dialog with a close button. I chose this approach to show the usage of simple dialogs:

func displayMessage(message: String) {
        let alertController = UIAlertController(title: “Result”, message:
            message, preferredStyle: UIAlertControllerStyle.alert)
        alertController.addAction(UIAlertAction(title: “Close”, style: UIAlertActionStyle.default,handler: nil))

        self.present(alertController, animated: true, completion: nil)

}

Now, let's try calculating something:

Tip

As I mentioned before, Autolayout is complex and probably annoying for beginners. But it's something that you're going to encounter all the time when developing for iOS, so it's necessary to get comfortable with.

Before you continue with the next lesson, try everything out. Choose few of your favorite apps and try to "copy" their UI in your project. All you have to do is to place the right components at the same spot and set constraints. Then switch between devices in the bottom part of Xcode and check whether everything works the way it should - components being at the right place, no unwanted spaces, and no other problems. You can also represent the components by Views of different colors, because what we're trying to practice is positioning and correct Autolayout settings.

Show that you're serious with iOS development and let us see the screenshots of your work in the comments section below :-)

In the next lesson, Introduction to the important TableView component, we'll go over TableView.


 

 

Activities (2)

 

 

Comments

To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

No one has commented yet - be the first!