iOS SDK: Build a Facts Game - Interface Creation

This post is part of a series called iOS SDK: Build a Facts Game.
iOS SDK: Build a Facts Game - Project Setup
iOS SDK: Build a Facts Game - Game Logic

This tutorial will teach you how to use the Sprite Kit framework to create a question-based Facts game. It is designed for both novice and advanced users. Along the way, you will apply the Sprite Kit core. The Facts Game tutorials are divided into three parts in order to completely cover each section. After this three part tutorial, the readers will be able to create a simple question-and-answer tap game featuring sounds, animations, menus, rules, timers, and UIKit interaction.


This series is divided into three parts: Project Setup, Interface Creation, and Game Logic. Each part will produce a practical result, and the sum of all parts will produce the final game. Despite the fact that each part can be read independently, for a better understanding and guidance, we suggest that the tutorial be followed step by step. We also included the source code for each part separately. Thus, providing a way to start the tutorial in any part of the series.

This is the second part of our Facts Game with Sprite Kit tutorial series. In this tutorial, you will program the level selection and main game scene interface. This tutorial focuses on several aspects such as, custom UITableView, custom class initializers, property lists, and SKActions. We will explain everything further below. If you haven't completed the first part of the series yet, you can download the project and pickup exactly where we left off.

This is what our end result will look like:

Illustration of the Final Result - Facts

1. Level Select

Step 1

The main objective of this game is to create multiple questions divided by several levels. This way, you need to form a customized interface to choose the level you want to play. In order to achieve this, you need to add another Objective-C class (File -> New -> File). Name it LevelSelect and choose the SKScene as the superclass. You will see two new files in your project.

For the level selection, you will use the UITableView view and configure it with several properties. Additionally, you also need to name the levels and their descriptions. In the LevelSelect.h you should add those properties. The following snippet will help you:

The snippet also contains a UIButton called backButton. At this moment, the button is self-explanatory; it helps the user go back from the level select interface to the main interface.

Step 2

Next, focus on the LevelSelect.m. The first step is to add the -(id)initWithSize:(CGSize)size method. In this class, you will only configure the background color. You can choose the color that you like the most.

Since you are using UIKit views, you need to add the -(void) didMoveToView:(SKView *)view method. This method defines and configures the backButton and tableView, places a title label for the view, allocates and initializes the levelsArray and the levelsDescriptionArray, and adds the tableView to the main view. The backButton can be configured as following:

Additionally, you must create the moveToHomemethod and import the MyScene.h.

Since you need to remove UIKIt views in more than one place, let's create a method that does exactly that. The method is called removeUIViews and is shown below:

The label to this interface is very simple. Try to program it yourself. If you have any problems, the following snippet will help you.

Step 3

The tableView configuration is a bit tricky since we need to configure several properties, like frame size and location, dataSource, and a delegate.

The second and third line of the aforementioned snippet requires an additional step since you are defining simultaneously two views. The data source of the UITableView is self-defined and the UITableView has an action delegate. In LevelSelect.h you should extend your class with UITableViewDataSource and UITableViewDelegate. Your LevelSelect.h should look like:

Since you are extending the UITableViewDataSource and UITableViewDelegate, additional methods need to be implemented, namely:

  1. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  2. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

The first is only used to know in real time the number of rows existing in the table view. The second method is complex, since it's used to populate and configure the table view. The table view configuration covers the title, description, and a row image. To use the description in every row, we must initialize each cell with the UITableViewCellStyleSubtitle cell style.

This method is responsible for an additional step: it verifies the current player's level and disables the levels ahead of the actualPlayerLevel. The full methods declaration can be seen below:


Here are two notes regarding the -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method. You have not yet initialized the levelsArray, levelsDescriptionArray, and actualPlayerLevel properties. All will be defined in the -(void) didMoveToView:(SKView *)view method. Do not forget to add the actualPlayerLevel property to your class:

Step 4

The levelsArray is defined with the names of the levels. You can call it "Level 1", "Level 2", or any other name of your choice. The levelsDescriptionArray follows the same principle, it is a description for each level and can be defined with names of your choice. A possible implementation is:

Finally, the actualPlayerLevel is a long value type that represents the level of the player. For now, say that the current level is 1.

The -(void) didMoveToView:(SKView *)view method ends when you add the table view to the screen:

Lastly, you need an additional change in the MyScene.m -(void) moveToGame method. You must call this new class instead of the old one. It can be easily achieved through:

At this point you should Run the project and test the new interface. You should see something similar to the next image:

Illustration of the Level Select Screen

2. Facts Interface

Step 1

The facts interface is where the real action occurs. The interface has several views that directly translates to properties, such as the number of lives remaining, current level, a timer, and true and false buttons. Moreover, for this class you will create a custom initializer. The advantage of this custom initializer is that we can progress through the game and values regarding the level. Also, lives are passed to the class and the class reacts (parses data) accordingly.

Once again, we will use SKLabelNode, UIButtons, and a NSMutableArray. The complete FactsScene.h is the following:

It is now time to move to the FactsScene.m and implement a few objects. You need additional objects to retrieve and store the data received by the initializer. Plus, you need to store the maximum time that a player has to answer each question. Modify the implementation file accordingly.

Now, you must write the initializer and store its values. The custom initializer is defined as a normal initializer and has the same structure. However, it has more properties as parameters. It should look like this:

Step 2

For now, the maximumTime is 30 seconds, but in the future the value will change to 60 seconds (or any other time of your choice). Now in the -(void) didMoveToView:(SKView *)view add a background image, front image, the player's lives, a timer, true and false buttons, and the current and total level's questions. For the background and front image the code is simple and you should be able to do it easily (using SKSpriteNode).

The player's lives are represented with a heart image. Since you will declare three lives, you must put three hearts in the screen. You will also use a NSMutableArray since we need to alter its size dynamically. The following snippet will help you:

The true and false buttons are configured as:

Note that both buttons call the touchWillProduceASound method. That method tests if a given answer is correct or incorrect. In this part, we only use one sound event (the false one).

Step 3

The game timer is a SKLabelNode that changes at every second. However, its initialization is done as a simple SKLabelNode:

To update the label, you need to create a SKAction that defines a custom timer to call a custom method. Then we must create a SKAction sequence:

You will see a warning regarding the - (void)updateTimer method because you haven't created it yet. That method does several actions simultaneously taking in consideration several properties:

  • Checks if the sound is on
  • Updates the maximumTime property and Label, decreasing by one value each second
  • Checks the maximumTime, and if the value is zero, it will either end the game or change to another question (more on this topic in the next tutorial)

We advise you to try to write the method using the aforementioned pseudo-code. But if you have trouble, the full method is presented below:

Step 4

One more method is missing, the removeUIViews. It removes the UIKit views from the view when a transition occurs.

It is now time to Run the project and see the Facts screen!

Illustration of the Facts Screen

3. Property Lists

Now it is time to add some data to the app. Go to File -> New -> File and choose the Property List (plist) file. Name it "LevelDescription" and configure it as follows:

Illustration of the Property List

In order to avoid putting all the data in the plist file, you can download the file directly on the zip file (beginning of the page). This tutorial does not cover in depth the data parsing, so in order to parse that file, the following snippet is used. If you have any doubt, use the comment box at the bottom of the page.

Now, Run the project and watch the console logs as you enter the Facts view. Note that the plist file can be configured in several different ways. If you want, you can change the Dictionary, Array types, and configurations. Note that changes must be declared in the parsing cycle. We strongly advise you to play a bit with plists file and the inherent data parsing.


At this point you should be able to use and configure a UITableView, interact between SpriteKit and UIKit frameworks, create SKTransitions and SKActions, and create and parse Property files. In the final section of this series, you will learn about Game Logic.