This is a three-part guest tutorial post by Johnson Ejezie, an Andela developer based in Lagos.
What we will be building
We will be using the traktv api to build a movie and tv show app. We will be figuring out functionalities to add to our app as the tutorial progress. We will encounter various concepts of iOS development and swift language while building the app and we will discuss these concepts.
What you will need for this tutorial
The UIKit (User Interface Kit) is the framework that defines the elements of the graphic interface for mobile application. Basically all components such as buttons, labels, views, switches etc are defined by the classes in UIKit.
Table views are among the most used components of the UIKit framework. Table Views present the user with data in a list format.
Like I said in the first part of this tutorial, we will be building an app that, among other functionalities, will be displaying a list of movies and tv shows. We will need a Table View to display this list. So lets see how we can create a Table View.
First we create our app. Open Xcode and click on Create a new Xcode project
By default, Application under iOS is the selected option in the list of options on the left pane. On the right pane, Xcode presented five options.
We won’t go into details; at least not now.
Select Single View Application and click next.
Enter the product name. We will call our app, tvzone. Enter your organization name. Enter the Organization Identifier which will be used to identify your app. All bundle IDs need to be unique. The org identifier is a way of making sure your apps (iOS, tvOS, MacOS) are separate from any other organization’s apps. It provides a prefix to the bundle ID.
Select swift as language and for devices select iPhone. Make sure Use Core Data is unchecked. We will add persistence later. Also ensure Include Unit Tests and Include UI Tests are both unchecked. We will have a separate tutorial for testing.
Click next. Select the folder you want to keep the app, click create.
I know Xcode looks intimidating if it is your first time. We will explain every part of it as we progress.
Go over to the navigator area. We want to delete the file ViewController.swift. Right click on it and select Delete.
In the popup, select Move to Trash.
Right click on the folder tvzone and select New File Under iOS, Source, select Cocoa Touch Class and click next.
For Subclass of, select UITableViewController and name the class “TableViewController”(This is not a very good name for a class. I know. This is for testing)
TableViewController: The UITableViewController class creates a controller object that manages a table view.
Click on the class we just created. Notice the boiler plate codes in Xcode Editor Area that come with UITableViewController; most if which are commented out. Delete all except the method viewDidLoad. We don’t necessary need it for now but I want to talk about it now.
ViewDidload: This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
Functions in Swift: A function is a set of statements organized together to perform a specific task. The syntax of function in swift is as shown below:
func: keyword used to notify swift compiler that this is a function.
funcName: name assigned to the function. parameterName: parameter passed to the function. parameterType: data type of the parameter.
returnType: the data type of the result that the function will return.
Time to write some code!
The first thing we want to do is declare an array containing the data we want to display in our table.
The first thing you must have noticed is the let keyword. This key word defines a constant. The names variable we declared can not be changed afterwards because its a constant. The var keyword is used to define a variable that can be changed.
Age is now 21. Xcode will throw error if we write the above code using let.
names, is the name of the variable we declared and it contains a list of names. This datatype is called an Array. Arrays: Arrays are variables that contain an orderlies of values. The values stored in an array must be of the same type. Our array contains only values of type String. This is not allowed:
This is not allowed because 42 is of type int and not String.
An index is assigned to every element in an array starting from 0. To access a value/element in an array, we use the index of that element. If we print:
we get Vilma Hammell. Remember the first element in the array is given an index of 0, the second index 1…
If you like to know more about array right now, go here.
Next we have write code that will display the content of the array “names” on a tableView. To do this, we have first talk about dataSource and delegate.
The data source provides the table-view object with the information it needs to construct and modify a table view. The dataSource implements the UITableViewDataSource protocol, which basically consists of a number of methods that define title information, how many rows of data are to be displayed, how the data is divided into different sections and, most importantly, supplies the table view with the cell objects to be displayed.
The delegate implements the UITableViewDelegate protocol and provides additional control over the appearance and functionality of the table view including detecting when a user touches a specific row, defining custom row heights and indentations and also implementation of row deletion and editing functions.
We only have to implement the datasource method for now.
Just after viewDidLoad, write this
2. numberOfSectionsInTableView method is called by the table view to get the number of sections to create. We only want one section, so we return 1
We are almost done. The controller is done, we only need to do some setting on the view. Click on Main.storyboard.
Storyboard is where we will design user interface. When we created the project, Xcode generated a viewController.
Select the viewController by clicking on empty space at the top where 3 icons reside. Hit backspace/delete.
We need a Table View Controller, not a viewController. Go to object library and start typing “table” in the filter:
Drag a Table View Controller to the editor area.
First thing we want to do is assign a class to our Table View Controller. So click on the yellow icon at the top of the Table View Controller we just dragged in. Go to the Utility Area.
Click on identity inspector; the third icon from left at the very top. For the field class, type in the name of the Table View Controller we worked on.
Select the table view cell; the white rectangle with Prototype Cells written on it.
Remember in our Table View Datasource, the cellForRowAtIndexPath will want to reuse a cell we identified as “Cell”. To enable the controller find this cell, we have to give the cell a reuse identifier. To create or reuse cell we did:
Pay attention to dequeueReusableCellWithIdentifier, where we passed “Cell” as the identifier.
With Prototype cells selected, go to the Utility Area and click on Attribute inspector(third icon from right)
For the field identifier, type “Cell”.
We are done. Lets go ahead and test it. Go to the Toolbar area on Xcode.
Select the simulator you want to run the app on. Mine is iPhone 6.
Hit the play button on the toolbar area or press command + R on keyboard. Wait for Xcode to Build and Run the app.
If you ended with a black screen as I did, it is because we did not set the initial View Controller. Check the debug area, Xcode has a message for us.
Main.storyboard can take more than one storyboard. The only way to know which View Controller to show first, is to set in on the interface or via code. In other words, we have to set the entry point of our app.
Go to the storyboard. Select the table view. With Attribute inspector selected in the Utility area, you will find Is initial View Controller right under View Controller section.
Check the box next to it and run the app again. This time, it should work just fine.
There is another way to create a table view using View Controller and not Table View Controller. Lets quickly go over it.
Delete the Table View in the storyboard. Go to Object Library and drag a View Controller into the editor. Look for Table View in the object library.
Note: Table View, not Table View Controller.
Drag the Table View and place it on the View Controller. You should have something like this
With the table selected, click on Pin icon on the bottom right of the editor area. Pin is the second from right.
We want to pin the table view to the top, left, right and bottom corners of the View Controller.
For each corner in the pin, set to zero and click on the faint red red line on each corner to activate the constraints.
Uncheck Constrain to margin. Go to Update Frames, select Items of New Constraints.
Click on Add 4 Constraints. Your View Controller should look like this.
It’s ok if you don’t understand what we just did now. We will discuss auto layout in part 3 of this tutorial.
Next we want to set the data source and delegate for the Table View. Holding the Ctrl button on your keyboard, click drag from the table view to the yellow icon on the View Controller and release.
Select datasource from the popup. Repeat and select delegate. Our view controller is now wired up to act as the data source and the delegate of the Table View.
Note: We didn’t have to do this for Table View Controller because this is already set in it.
Now we have to create a View Controller class for the interface we just created. Delete the Table View Controller class. Right click on tvzone folder and select New File. The class should be a subclass of UIViewController. Call it “ListViewController”.
Delete very code in the class, including viewDidLoad. Create an array of names. Similar to what we did in Table View Controller class.
To be able to act as data source, our ListViewController must extend UITableViewDataSource and conform to it’s protocol.
Outside the View Controller class, we extend the ListViewController and implement the UITableViewDataSource protocol.
ListViewController should look like this:
The only new term here is extension. Extensions let you extend and add new functionality to an existing type, class, structure or enumeration. You can extend existing types, both your own and those from external libraries or those from Swift itself.
Get back to storyboard. You should be able to do the following yourself:
Run the app now. Easy!!
Let’s quickly add an image. Get two image of your choice. I will be using photo of messi and ronaldo. Don’t ask me who is a better player between the two.
Adding Image to Xcode
Click on Assets.xcassets in navigator area. drag the images from finder to the editor area of Assets.xcassets. Note the name of the images.
Go to ListViewController class. cellForRowAtIndexPath is where we configure our cell. We don’t have different images for each cell, so we’ll be alternating between the two images we have.
Aside having a textLabel property, UITableViewCell has imageView property. The imageView is of type UIImageView.
A UIImageView object displays a single image or a sequence of animated images in your interface. Image views let you efficiently draw any image that can be specified using a UIImage object.
A UIImage object manages image data in your app. You use image objects to represent image data of all kinds, and the UIImage class is capable of managing data for all image formats supported by the underlying platform.
In cellForRowAtIndexPath method, add the following code just before returning the cell.
If statement is a conditional statement we use to check a condition and execute a group of instruction if the condition is true. When used together with else, then we can execute a different group of instructions if the condition is false. The syntax for if..else statement is show below:
Since we want to alternate between Messi and Ronaldo images, we check if the integer indexPath.row is an even number. If it is, use Messi’s image. If it is not, use Ronaldo’s image.
The symbol % is call modulus operator and it simply return the remainder of after an integer/float division.
If the remainder is zero, then indexPath.row is even.
UIImage(named: “messi”) is simply initializing/creating a UIImage using the image asset name “messi” We then assign this image to the image property of the cell’s imageView.
Go ahead and run the app now.
It’s not that pretty, that’s ok for now. In part 3 we see how to build a custom UITableViewCell for our movies/tv shows app. Something like this.
AppDelegate: According apple doc,
The app delegate works alongside the app object to ensure your app interacts properly with the system and with other apps. Specifically, the methods of the app delegate give you a chance to respond to important changes. For example, you use the methods of the app delegate to respond to state transitions, such as when your app moves from foreground to background execution, and to respond to incoming notifications. In many cases, the methods of the app delegate are the only way to receive these important notifications.
info.plist: An information property list file is a structured text file that contains essential configuration information for a bundled executable.
launch Screen: The screen that appears instantly when your app starts up.
Here is the link to the project we worked on in part two. We will build on this. The project was initially written in Swift 2.2 but I have updated it to swift 3. In part 2 we agreed will be building a custom cell to display each movie/tv shows. Here is a screen shot of what we want to achieve.
At the top we have a label for the name of the movie/tv show. Right below the name is an image. Next is a label for the release date and finally a summary/synopsis. Also the cells is designed as cards with the edges curved a bit.
Lets get right into it.
Right click on tvzone folder, select New File > Cocoa Touch Class. Click on Next. For “Subclass of:” select UITableViewCell. Check Also create XIB file. Name the class MoviesTableViewCell. Click next, click Create.
Click on MoviesTableViewCell.xib. This is where we will design the custom cell and support it with little code.
Select the cell, click on size inspector. For Row Height check custom, and give it a height of 350. Below RowHeight you will find Width and Height properties of the cell. Set width to 320 and height to 340. We will let the content of the cell determine the size of the cell but for now 350 gives us a size to work with in the interface. The editor area should look like this now
Drag a view from the Object library onto the cell’s Content View. With the view selected, click on Pin and pin the view to all corners of the content view. top:5, bottom:5, leading:8, trailing:8.
Let’s call this view, “Card View”. To do this, click on identity inspector, just right below “Document” you will “Label”, enter “Card View” for the field.
Create an IBOutlet for the view. You do this by opening the assistant inspector and click > dragging (while holding control button) from card view to it’s class. Call the outlet cardView.
Notice the “Spring Wood” color of the background of the card in the screenshot. Lets apply the same color to our card view. We will do this in a UIView method called layoutSubviews. According to apple:
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
Though layoutSubviews sounds likes where we can only alter the layout/frame of our subviews, we can also take advantage of it to alter some other components of the subviews that doesn’t relate to the views frame.
Now let get back to cell interface. Grab a label and place inside card view. Pin it 8 to the left and right and 4 to the top. With the label selected, go over the Utility Area, select Attributes inspector. Let’s change the font. Click on the bold “T” to the extreme end of font field.
For font, click on the drop down and select Custom, for family select Avenir, for style, select Medium. Give it a size of 20.
Right underneath Font is Alignment. Select the second option to center the text in the label.
Go to the Object Library, get an ImageView and drop it vertically right next to the label. Pin the image view 8 to both left and right. 4 to the top
Next we add two more label. One for year of release and one for summary.
Year of release label: Pin 4 to the image view, 8 both left and right of card view. Change font to Avenir, style: Book, size: 15.
Summary label: Apply same font for year of release. Pin 4 to Year of release label, 8 left and right. Pin to the bottom too.
With the summary label selected, go over to Size Inspector. scroll down to the constraints. Lets edit the bottom constraint. Click on edit on the “Bottom Space to:SuperView”.
Change Constant to >=, and the value to 8.
This will allow card view to make space enough for the summary label content.
With the label still selected, go back to attribute inspector. Right below Alignment is Lines. UILabel has a property called “numberOfLines” which specifies the maximum number of lines to use for rendering text. We will set this to 0 since we don’t know the actual number of lines we will need for the summary text.
At this point, our cell should look like this
Lets go ahead and wire the elements to the class.
Click on Assistant editor. Make sure the MoviesTableViewCell file is the one displayed in the assistant editor. While holding down control on keyboard, click and drag from the first label to MoviesTableViewCell class. Call the outlet titleLabel. Do the same for the imageView (movieImageView), year of release label (releaseDateLabel) and summary label (summaryLabel).
Finally we can concentrate on code now. Go over to ListViewController. Our table will be displaying a list of movies so we can go ahead and delete the “names” array. We create an array called movies. This will be an array of dictionaries. Our table will display a list of two movies. Since we already have a picture of Messi and Ronaldo, let create a movie for the two stars.
For summary I just grabbed something from the Wikipedia.
The table view has no knowledge of the existence of our custom cell, we have to register the cell. We will do this in viewDidLoad. But first, go to main storyboard and create an outlet for tableView. Call it tableView.
So the tableView can be a able to dequeue the custom cell, we register a nib object containing the custom cell with the specified identifier.
Go to MoviesTableViewCell.xib and give the cell a reuse identifier MoviesTableViewCell
You must noticed an error from the moment we deleted the array names. Let fix that. For numberOfRows return
We change the implementation of cellForRowAt indexPath
We create the cell and forcefully cast it to type MoviesTableViewCell. This is fine since we are sure it is of that type. The movies array is an array of dictionaries. We can grab each dictionary/movie using indexPath.row each time cellForRowAt indexPath is called. This we did with the line of code
We then set the cell contents by accessing the values of the dictionary using the keys. Finally we returned the cell.
Run the project now.
That is not what we want to achieve.
We forgot to set the size for our cell. To do this, we will implement two method from UITableViewDelegate.
The first method asks the delegate for the estimated height of a row in a specified location. While the second asks the delegate for the height to use for a row in a specified location.
If we have a fixed size for our cell, we could return that size. Say we want our cell to be height 250, then we return 250. In this case we don’t have a fixed size. We want the cell to take the size of it’s content. UITableViewAutomaticDimension requests that UITableView use the default value for a given dimension.
Before we run the project, go main storyboard, and set the delegate for the table view. Same way we set the datasource in part one.
Run the project.
The complete project can be found here.
In part 4 we will be adding traktv api and see how to pull content from a web service.
Background M-Pesa is a mobile phone-based money transfer, financing and microfinancing service, la...
The Andela Learning Community (ALC) is happy to announce a new learning track for graduates of the G...
Tap into a global talent pool and hire the “right” developers in days, not months.
Accelerate your career by working with high-performing engineering teams around the world.BECOME A DEVELOPER
We take great pride in matching our developers with the best partners. Tell us about your team below!