Create Streaming app Home Screen on tvOS

atul khatri
4 min readJul 12, 2021

(Part 5 of 8)

This is the fifth part of our tvOS Bootcamp. Please check out the previous pages to know more about this series.

In this tutorial, we are going to create several view components to render a list of Movies or Series in our app.

This is how the Home screen is supposed to look as per our mocks:

Since our HomeViewController is common for both, we will differentiate the type of data using a property of type HomeScreenType enum, it can either be .movies or .series.

As the UI shows, we need to integrate various carousels, each having a title and a horizontally scrollable list of data (assets).

The approach we would take to create this is by using a parent UICollectionView which will contain a list of carousels.

Each carousel would be in fact a part of another UICollectionView which would be rendered inside a UICollectionViewCell with scrollDirection set to horizontal.

In our app, RailCell is a cell which contains a horizontal collection view having a list of AssetCell objects, each representing a Movie or Series.

Firstly, we will create the parent UICollectionView in our XIB and create its outlet in our class. We will then setup this collection view in a method called setupView()

Here we setting the datasource & delegates of this collectionView.

We will also register the carousel cells named RailCelland section header view called RailHeaderView. This view contains a title to be shown on top of each carousel/rail.

Next step is to implement the UICollectionViewDataSource & UICollectionViewDelegateFlowLayout.

UICollectionVieDataSource is implemented like this:

Number of sections would be equal to the number of carousels we need to show. Thus, we are returning data array count from PageModel. We will shortly see how to fetch this page using NetworkManager.

Number of items in each section are restricted to 1. That is because we need to show only a single cell in each section. This cell will in-turn show a horizontal list of data.

In third method, we are simply creating an instance of RailCell using standard format and loading its data using loadData method.

We are also using a closure to know when a cell inside the nested collection view is tapped in order to open the Detail scree using openDetails method.

Last method of this delegate returns an instance of RailHeaderView, used to show the header on top of the carousel.

To mention the sizes of each carousel cell & header, we need to implement UICollectionViewDelegateFlowLayout

Here we are simply returning the desired size of the carousel cells based on the screen type. Please note that we have also created a class named Constants to hold all our static data to make them dynamic.

Second method returns the size of the header.

Now that we have linked our UI, let’s go ahead and fetch data for Movies or Series like this:

This method uses type enum to identify what kind of data is required for Home screen. Based on that, appropriate method from NetworkManager is used to fetch data.

Please note that both of these methods return a same type of data with the only difference at the view level. Movies cells are shown in Portrait mode whereas Series cells are shown in Landscape mode.

This is how the loadData method looks like:

Before seeing the data, we need to discuss how nested UICollectionView is created inside RailCell.

Firstly, we will create a file named RailCell, it will be of UICollectionVieCell type. We then need to integrate a UICollectionView inside the XIB and create an outlet in respective swift file.

This is how the file looks like:

Starting from the beginning, this class contains a property RailModel which is provided externally using loadData method.

UICollectionView is being setup the same way like we did in HomeViewController above.

This is how the datasource and delegates look like:

There are many important things to note here in order to achieve the correct Focus behaviour in carousels.

We need to set the canBecomeFocused property of the carousel cells RailCell false. On the contrary, we need to set focus for each asset true using collectionview delegate method. This will ensure that carousel cells are not stealing focus from the child cells.

Data in each asset is loaded by using a method loadData in AssetCell. Let’s take a look at its implementation.

AssetCell is simply a blank UICollectionViewCell. We are making use of system provided UI using TVUIKit. This framework provided by Apple and it contains a few boilerplate views which could be used in tvOS apps.

For example TVPosterView in our project is used inside AssetCell to show an image and a title. One important advantage of using system defined UI is that it guarantees to appear great in all sizes. It also has the focus animation in its imageview and the title has a slight “Marque” effect when a user rests on a specific cell for a few seconds. Developing all of these require additional effort hence are avoided from the initial implementation of this bootcamp.

Now we will just run the app and our beautiful UI would be rendered.

Home Screen

Our next task is to make all of these clickable by implementing a Detail screen.



atul khatri

Software Engineer (iOS) @ Meta | Tech Enthusiast | Learner