Part 4: (inter)Face-Off

Yvette
10 min readDec 28, 2015

--

This is Part 4 of the Getting Started with TDD in Swift tutorial. If you haven’t done the first 3 parts of this tutorial, now might be a good time to go and take a look.

At the end of Part 3 our app had a working brain, and a game engine that could check a player’s answers and keep track of the score.

Now we need to create an interface for our game, so users can actually play with it.

First though we need to quickly go into some theory about how we architect mobile apps.

Model-View-Controller (MVC)

MVC is a popular software design pattern in web and mobile. It is based on separating your app code into 3 distinct roles:

Model

The model represents the data in our app, and holds the logic for what we do with that data. In our FizzBuzz app the Brain and Game are part of the model.

View

The view is the user interface. It’s what the user sees and interacts with. In iOS development you can create views graphically with Storyboards.

Controller

The controller manages the communication between the view and the model. It takes the data from the model and communicates it to the view for display. The controller also takes the user’s input and communicates it back to the model. In iOS, controllers are called ViewControllers.

In our app, the view controller will take in the user’s interaction with the view (i.e. tapping the Fizz button), communicate to the model (the brain). The model will check if the move is right or wrong, and communicate this to the view controller. The view controller will then change the view to let the user know whether they were right or wrong.

This tutorial will focus on building the View for our app, then in the next part we’ll do the View Controller.

Testing Views

Way back in the days of Xcode 7 UI Testing was introduced, which was cause for much celebration — before this developers had to use a variety of 3rd party libraries in order to test their UI.

One of the best features of UI Testing in Xcode is recording — it allows you to record tests by using your app in the simulator, and the “test” part code is generated for you. All you then have to do is add in the expected end result.

However, in order to use UI Testing as it was intended, the UI needs to already be in place. Whilst it is theoretically possible to write the tests before implementing the UI, it goes counter to the Xcode’s style of UITesting.

So, just for this part of the tutorial we will put test driven development aside — although we can still use the lessons it’s has taught us. We’ll build in small steps, testing the changes by running the app in a simulator to check we are on the right track.

Download the image assets you’ll need here.

  1. First, the fun bit: picking colour scheme!

Head on over to Color Hunt and pick a color scheme that catches your eye (or just use the one below).

Our app will have 4 colors:

My color scheme, but do pick your own!

Make a note of the hex-codes for the 4 colors in your scheme, and make sure Color #2 is visible against the other colors!

2. Now you have your color scheme ready, let’s check out what we’re building:

The four buttons in the middle are the ways the user will jump to the next number, entering “Fizz”, “Buzz”, “FizzBuzz”.

3 / 5 is a label to show what the Fizz and Buzz numbers are.

The “Play Again” button is hopefully pretty self-explanatory!

3. Now we have our design and our colors, let’s get started.

In Xcode, open the Main.storyboard file. Storyboards are a popular way to create the views for your app, and definitely the easiest to learn when you are getting started.

“A storyboard is a visual representation of the app’s user interface, showing screens of content and the transitions between them.”

Storyboards are edited using Interface Builder, a visual interface editor that come packaged with Xcode. Right now your storyboard should have one empty scene. Which is kinda dull.

4. First, let’s set the background of our view.

Set your storyboard to display as an iPhone 8 in Portrait Mode using the control panel at the bottom of the window.

On the Outline View, select the View of your View Controller Scene. (yes, that’s a lot of views. Sorry.)

To change the background color of the View you need the Attributes Inspector in the Utility Area.

Select the Background field, and click ‘Custom’. In the pop-up, select the second tab (the one with the sliders), or press ⌘ + 2, and in the Hex Color # box, put the Color #1’s hex color code.

The background of your View should now be whatever vibrant color you chose!

5. Next, let’s add the “Play Again” button.

Bring up the Object Library, and in the search box at the bottom type ‘button’. Then click + drag the Button onto the bottom-right corner of the View

6. Now we have a button, for now we just need to update the text. We’ll deal with the functionality later.

CHALLENGE 1: Using the fields in the Attributes Inspector, change:

* Title of the button to ‘Play Again’.

* Text color to your Color #2.

* Font to ‘Avenir’ and weight to ‘Heavy’

* Font size to 20

* Resize the label to fit the text in

Answer demo at the bottom of the page.

7. Let’s see how our layout behaves on a different device size. In Xcode 10 we can check out our layout in different device sizes without having to run our app (which is cool!).

However when we look at it on an iPhone 4s, there’s something odd. There’s no sign of our button. And on an iPad it’s in the middle of the screen!?

The problem is that we haven’t give any constraints on our button, which would tell the view where to place it. So it’s ended up off-screen on the iPhone 4s, and in the iPad it’s just off-centre.

What we actually want is for it to be pinned to the bottom right of the screen, no matter what the screen’s size. We do this with constraints.

Go back to the iPhone 8 view. To add constraints between the button and the view:

  • select the button
  • hold down CTRL, and click + drag from the button to the bottom right corner of the view.
  • In the menu that appears, hold down SHIFT and tick Trailing Space to Safe Area and Bottom Space to Safe Area.
  • Hit Enter to save the constraints.

If you see dotted lines around the view, this is Interface Builder telling you that the view isn’t precisely where the constraints say it should be. Press ⌘ + ALT + = to move the view to where it should be.

Now, check out the iPhone 4s and iPad views again. The button should now be neatly pinned to the bottom-right of each screen.

Even though we don’t have tests for this, I think that deserves a high-five.

CHALLENGE 2: Add a label with the text “3 / 5” , pinned to the top right of the screen. Give it the same formatting as the Play Again button.

Demo of the answer at the bottom of this page.

8. Next, we need to work on the centre four buttons.

In order to keep the view hierarchy neat, we’ll group the buttons together in their own view. Grab a View from the object library, and click+drag it to the middle of your main View. You’ll know it’s in the exact centre when the blue tramlines appear horizontally and vertically. To avoid confusion we’ll call this new view the GameView.

To fix it to the centre of the View, CTRL and click+drag from the GameView to the main view, and tick Center Horizontally in Safe Area and Center Vertically in Safe Area.

You’ll notice the red lines that appear. This is warning us that there’s not yet enough constraints for Auto Layout to determine the exact sizing and placement of the GameView. If you run the simulator now, you won’t see the GameView — it’ll be there in the centre of the screen, but 0 height and 0 width!

We could give the GameView an absolute height and width (of say, 200 pixels), but this means it’ll be the same size regardless of the screen size. It’ll be too big for an iPhone 4 screen, and too small on an iPad Pro! Instead we need to think of the sizing as relative.

9. To keep things simpler we’ll make it so the app is only playable in Portrait Orientation. To set this click on the FizzBuzz target, and untick the Landscape Left and Landscape Right options.

10. Now back in the Main.storyboard we can set the rest of the GameView constraints. We want it to be square, and always 40 pixels away from the vertical edges of the screen.

Step by step:

  1. Create a Leading Space to Safe Area constraint between the GameView and main View
  2. Change the constant value for this new constraint to 40.

3. Create an Aspect Ratio constraint for the View.

4. Set the multiplier value for this to 1:1

Once we’re happy with the placement of the GameView, you can change the background color to Clear (the default).

11. Now to add the buttons!

CHALLENGE 3: Add a button inside of the GameView. Add the following constraints:

* Leading Space to Container: 0.

* Top Space to Container: 0

* Equal Width and Equal Height to the GameView.

* Change the multiplier value for the height and width constraints to 0.48

Demo of the answer at the bottom of this page.

12. The first button will display the current score, so change:

  • Title to “0” (zero)
  • Text color to white
  • Font to Avenir Light
  • Font size to 70

13. As you see in the UI design our buttons will have a rounded border. For this we’ll need to import a .png image into Xcode.

Download and unzip this file.

Navigate to the Assets.xcassets file in Xcode. Click on the + , and click Import …

Select the button_border.png image, and click import it.

Go back to the Main.storyboard, and select the button. Set the Background Image to button_border.

14. Next, let’s add the other 3 buttons. To copy an existing storyboard element, click it and ALT + drag.

CHALLENGE 4: Add 3 more buttons copied from the number button.

* Make all the buttons equal width and height to the Number button.

* Pin a button to each corner of the GameView.

* Delete the titles for the other 3 buttons.

Answer demo at the bottom of the page.

15. Now to add the icons for the other 3 buttons.

Import champagne.imageset, lightning.imageset and rocket.imageset into the Assets.xcassets file.

An imageset is a collection of the same image in different sizes — your app will use the correct image for different screen sizes and pixel densities.

Add the icons to the 3 buttons. If the buttons resize when you add the image, just reset by hitting ⌘ + ALT + =.

And that’s it! We’ve built an adaptive interface for our app, that will work on a whole range of screen sizes. Try it out on different devices in the Storyboard and Simulator to see and admire your good work

For simplicity, you’ve used plain white assets for the icons, text and button background. If you’d like to update them to fit in with your color scheme, you can use Sketch is the popular choice for image editing, and my favourite. Otherwise GIMP is a (forever free) alternative.

Next: Part 5: Joining the dots with View Controllers — the unit testing part

If you found this tutorial helpful, please 💚 it below and follow me!

Challenge 1 Answer Demo

Challenge 2 Answer Demo

Challenge 3 Answer Demo

Challenge 4 Answer Demo

Part 1
Part 2
Part 3

--

--

Yvette

iOS Developer | @makersacademy Alumni | Runner, Triathlete, ex-Rower | Feminist