Your First iOS App: 100% Programmatically (Xcode 7.2, Swift 2.1)

Part 2

This is Part 2 of a tutorial that follows Apple’s old “Your First iOS App” tutorial, but implements all of the user interface elements programmatically using Swift. View Part 1 or check out the complete code on Github. This tutorial is ported from an Objective-C implementation by Austin Louden. If you prefer Objective-C, please see Part 1 and Part 2 of that tutorial.

The next step is to add elements to the user interface — a text field, a button, and a label.

1. The Text Field

Go back to your MainViewController.swift file. Similar to the app delegate, this comes with some helpful methods to handle different points in the life cycle of the UIViewController class. It should look a little like this:

One of the important aspects of a good developer is clean code. Thus, you want to remove any code that you don’t utilize. In this case, go ahead and delete lines 10 through 26 as they aren’t relevant to this project.

Now, to add our text field, we’re going to lazily instantiate an Apple-provided class called UITextField. Lazy instantiation simply means that the object is only created when it is required by the program rather than having all the objects of a page created as soon as the page is created.

Below the viewDidLoad method, add the following code:

lazy var textField: UITextField! = {
let view = UITextField()
view.translatesAutoresizingMaskIntoConstraints = false
view.borderStyle = .RoundedRect
view.textAlignment = .Center

return view
}()

We set translatesAutoresizingMaskIntoConstraints to false in order to set our own custom constraints for the text field. Additionally, we set the borderStyle to RoundedRect to style the text field the way we want it.

Now, within the viewDidLoad method, which is executed immediately after the view is created and loaded on screen — add the following line to introduce your text field.

view.addSubview(textField)

Now that you have instantiated the text field, we need to tell it where to display on the screen. In order to do this, we will use a tool provided by Apple called AutoLayout.

Auto Layout dynamically calculates the size and position of all the views in your view hierarchy, based on constraints placed on those views. For example, you can constrain a text field so that it is horizontally centered within a view and so that the text field’s top edge always remains 8 points below the view’s top. If the view’s size or position changes, the text field’s position automatically adjusts to match.

In order to introduce your AutoLayout code, we need to override some built-in Apple layout methods. In order to do so, add the following line to your viewDidLoad method:

view.setNeedsUpdateConstraints()

Now, add the following method to your MainViewController class:

override func updateViewConstraints() {
super.updateViewConstraints()
}

The updateViewConstraints method is called when the view controller’€™s view needs to update its constraints. In order to add our own constraints, we override this method. Now, create a new method called textFieldConstraints under the updateViewConstraints and add the following constraints that will properly place our text field within our view.

Finally, add the following line to updateViewConstraints in order to call the layout code for our text field. Be sure to add it above the super.updateViewConstraints method.

override func updateViewConstraints() {
textFieldConstraints()
super.updateViewConstraints()
}

Your MainViewController class should now look like this:

If you run the app, you should now see the text field at the top of the screen. Clicking inside will bring up the keyboard and allow you to type. While the keyboard appears automatically, we have to add to code make it disappear ourselves.

The key is implementing a “delegate method” of the UITextField. Delegate methods are like helper functions for the objects in your application, and can sometimes help pass data between two classes. The delegate method we need to dismiss the keyboard is called “textFieldShouldReturn”, a function that is called every time the user presses the “return” button on the keyboard.

Information about a class’s delegate methods is in Apple’s documentation. You can find the “textFieldShouldReturn” method in the UITextFieldDelegate reference article.

Add it below your viewDidLoad method:

func textFieldShouldReturn(textField: UITextField!) -> Bool {
}

Dismiss the text field programmatically by adding the following lines:

func textFieldShouldReturn(textField: UITextField) -> Bool {   
   // Dismisses the Keyboard by making the text field resign
// first responder
textField.resignFirstResponder()

// returns false. Instead of adding a line break, the text
// field resigns
return false
}

We need to do a few more things before this works. Go back to the viewDidLoad method where you added the text field. Right below super.viewDidLoad() line, add

textField.delegate = self

This lets the application know where to look for the implementation of the delegate methods, which in this case is inside Self — a reference to our MainViewController class.

The last thing we need to do is update the “MainViewController.swift” file. There, you’ll find the line:

class MainViewController: UIViewController {

Change it to:

class MainViewController: UIViewController, UITextFieldDelegate {

This tells the MainViewController that it implements delegate methods of a UITextField object. The MainViewController should now look like

Run the app — pressing the return button should now dismiss the text field.

2. The Button

Now, add the button in the viewDidLoad method as well. Ensure that you add the button below the textField creation.

view.addSubview(textField)
view.addSubview(button)

Similarly, we’ll lazily instantiate the button. Add the following below the lazy instantiation of the text field.

lazy var button: UIButton! = {
let view = UIButton()
view.translatesAutoresizingMaskIntoConstraints = false
view.addTarget(self, action: "buttonPressed", forControlEvents: .TouchDown)
view.setTitle("Press Me!", forState: .Normal)
view.backgroundColor = UIColor.blueColor()
    return view
}()

This takes care of most of the button’s properties. The addTarget, action, forControlEvents method allows you to specify a function that’s called when the button is pressed. The target is the object to which the action message is sent — in this case, self. The action performed after the button is pressed is identical to what would happen if you called

buttonPressed()

Wrapped in quotes is the name of the function to be called when the button is pressed — we still need to implement this.

The control event specifies the type of interaction required to trigger the button. Apple’s “UIControlEventTouchDown” is the way to specify just a simple tap.

We also need to add the layout constraints for the button. Add a buttonConstraints method below the textFieldConstraints method

Additionally, add the method call to the updateViewConstraints method.

override func updateViewConstraints() {
textFieldConstraints()
buttonConstraints()
super.updateViewConstraints()
}

Now we can create the shell of the buttonPressed function. We need to create the label before we can implement the full thing.

In between viewDidLoad and textFieldShouldReturn, create the buttonPressed method:

func buttonPressed() {

}

We’ll come back to this after we create the label.

3. The Label

I’ve saved the easiest for last. We’ll create the label below view.addSubview(button) line in viewDidLoad

view.addSubview(textField)
view.addSubview(button)
view.addSubview(label)

Now to lazily instantiate the label:

lazy var label: UILabel! = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.text = “Hello World!”
view.textAlignment = .Center

return view
}()

add a labelConstraints method below the textFieldConstraints method

Finally, add the method call to the updateViewConstraints method.

override func updateViewConstraints() {
textFieldConstraints()
buttonConstraints()
labelConstraints()
super.updateViewConstraints()
}

Run the app, and you should see the familiar “Hello World!” above your button.

4. Changing the Label Text

Only one thing left to do. Since you’ve already created the shell of the button pressed method, we just have to add a line that sets the label text equal to the string in the text field. This is done with one line inside buttonPressed:

func buttonPressed() {
// Print Hello followed by the user inputed string
// The exclamation point is added to unwrap the optional
label.text = "Hello, \(textField.text!)"
}

You can print a value within a string by adding

\(yourValue)

with your value in parenthesis. This is demonstrated in the buttonPressed method above.

That’s it! Run the app and try it out.