Connecting the UI to Code

So in Android, we have “Activities” that are connected to “XML” layout resource files. With Swift, each scene is essentially the XML layout file while, while each associated “.java file” is represented as a ViewController class in Swift. But, besides for this analogy, here is the official definition from the Apple docs:

View controllers implement your app’s behavior. A view controller manages a single content view with its hierarchy of subviews. View controllers coordinate the flow of information between the app’s data model, which encapsulates the app’s data, and the views that display that data, manage the life cycle of their content views, handle orientation changes when the device is rotated, define the navigation within your app, and implement the behavior to respond to user input. All view controller objects in iOS are of type UIViewController or one of its subclasses.

 

So essentially, in an average app, you’ll have a bunch of scenes and a bunch of associated View Controllers, just like in Java. But instead of changing scenes with “intents”, you would use the storyboard, which we’ll go into in depth later. For now, we’ll go over how to reference actual views in Xcode. You’re probably extremely familiar with Android’s `Button b = (Button) findViewById(R.id.buttonId)`, but in Xcode, we reference our views in the code through a visual drag and drop. These references are called outlets. Let’s connect our TextView into the code:

1. In Main.storyboard., open the assistant editor. It’s the button with two circles that looks like a venn diagram. This will pull your ViewController side by side from your actual visual editor. You’ll probably find that the IDE looks really crowded with so many panels, but you can close the left and right panels using those last three buttons in the screenshot below.

2. In your storyboard, which should be on the left hand side now, select the text field and Control-drag it into the Class. You should see a blue line appear, and drag it right below the class declaration (the `class ViewController: UIViewController {`)

3. Name your variable, and watch it appear in the code:

4. This following line of code is your textview object. Notice the syntax in Swift (it’s like C). We say “IBOutlet” which references the text view in your UI. It’s kind of like findViewById. Then we have “weak”, which basically says that the system has the power to kill the TextView, but that won’t happen since your textview is superclassed in a much stronger parent view. After this we have “var”, then the name, then a colon, then the type of object, then an exclamation point, which basically tells the system that myTextViewObjectInCode will always be assigned (in this case to a UITextView).

ACTIONS:

Notice that this view reference is called an Outlet. There are other options as to how you can link the UI to the code. One of these options is an Action. Earlier, we had ctrl-dragged our textview to our code without changing the Connection property:

Lets do the same Ctrl-Drag with our button, but this time drag it to below `func didReceiveMemoryWarning()` and change the connection type into `Action`.

And press “connect”!. You’ll have created a function that looks like this:

@IBAction func myButtonAction(_ sender: Any) {

}

Here, instead of @IBOutlet, we have @IBAction, which specifies that we have added an Action. Then, we have “func” which indicates it is a function called “myButtonAction” and the parameters specify that any object can call the Action, but it would also work fine if you changed “Any” into “Button”.

We can compare Actions to onClick() methods in Android.

But right now, our button isn’t doing anything! Let’s make it change the text of our Text Label that we defined in our code earlier (by doing the ctrl drag). Write the following code in the method:

`myTextViewObjectInCode.text = “Whoo hoo”`

Okay so this code should change the text of our UITextView when we press our object. Go ahead and run the simulator (we talked about this in the last tutorial) and push the button:

Okay cool, so we can change the text using a button. But now let’s let the user type in their own text, press submit, and see their text appear in the app. To this, we will use a text field delegate. Essentially, we’ll set up our main class (or our main ViewController) as our delegate by editing the class heading and adding a line of code into our Outlet method we created earlier. This will let us receive callbacks from the textview (or text field in IOS) directly in our main class (or View Controller in IOS).

But here’s the official implementation of a delegate from the Apple docs:

“A text field’s delegate communicates with the text field while the user is editing the text, and knows when important events occur—such as when a user starts or stops editing text. The delegate can use this information to save or clear data at the right time, dismiss the keyboard, and so on.”

In order to have our ViewController file act as a delegate, we need to “implement” UITextFieldDelegate into our class. This is similar to how we can set “setOnEditorActionListener” in Android. So, edit your class heading into the following:

  • class ViewController: UIViewController, UITextFieldDelegate {

The last thing you need to do to set up the delegate is add the following line of code in your viewDidLoad:

myTextViewObjectInCode.delegate = self

Altogether, you should have something like this:

This is basically the same thing as implementing an Onclicklistener in Android. So we also will have to implement the associated methods (or functions in this case). Here are the ones we will implement:

  • func textFieldShouldReturn(_ textField: UITextField) -> Bool
  • func textFieldDidEndEditing(_ textField: UITextField)

Here’s how we’ll implement them. Look at the comments:

func textFieldShouldReturn(_ textField: UITextField) -> Bool { //Asks the delegate if the text field should process the pressing of the return button.

// Hide the keyboard.

textField.resignFirstResponder()

return true //We wan’t to let the system just treat this as normal. This means that after the user presses the return button, the system will automatically call textFieldDidEndEditing

}

func textFieldDidEndEditing(_ textField: UITextField) { //Called when the user presses return

myTextViewObjectInCode.text = textField.text //Sets the text to whatever the user enters

}

So now, myTextViewObjectInCode should change into whatever the user enters instead of “Whoo hoo” when the user enters text and presses submit. Go ahead and run this code on the simulator and try it out! In the next tutorial we’ll look into storyboards more in depth and try to better understand the lifecycle of an IOS app.