CHAPTER 4

image

Creating a Photo Gallery App

For the next few chapters, we will be exploring some of the more common Apple TV user interface elements while building a Photo Gallery application. Most of the user interface elements will be familiar to you if you are an experienced iOS developer, but the way that the user interacts with them is somewhat different since you cannot walk up to your television and start tapping and swiping on the screen. (Not yet, anyway!)

Page View Controllers

The first user interface element that you will be exploring is the Page View Controller. The Page View Controller consists of a number of full-screen views that the user navigates through by swiping left or right between them. A common component of the Page View Controller is the Page Control, which is a series of horizontal white dots along the bottom of the views to indicate both the number of pages available as well as which page the user is currently viewing. An example of a Page View Controller containing a number of full-screen images is shown in Figure 4-1.

9781484217146_Fig04-01.jpg

Figure 4-1. An example of a Page View Controller and its associated Page Control

From the Page Control near the bottom, you can see that there are five pages in this Page View Controller, and the user is currently looking at page number three.

For the Photo Gallery app, you are going to create an app consisting primarily of a Page View Controller that will present the user with a series of full-screen Image View pages. With each page containing a different photo, this will really take advantage of the full 1080p high-definition screen available to an Apple TV app.

Creating the Photo Gallery App

  1. To get started creating the Photo Gallery app, open Xcode and select File image New image Project.
  2. Next, choose Application under tvOS, then Single View Application, as shown in Figure 4-2.

    9781484217146_Fig04-02.jpg

    Figure 4-2. Creating a new Single View Application tvOS project

  3. After clicking Next, enter Photo Gallery for the Product Name and choose Swift for the Language, as shown in Figure 4-3.

    9781484217146_Fig04-03.jpg

    Figure 4-3. Creating the Photo Gallery Project

  4. Click Next again and choose a location (for example, your Desktop or Documents folder) where you would like to save the project, then click Create.

You should now be looking at your newly created Photo Gallery project, as shown in Figure 4-4.

9781484217146_Fig04-04.jpg

Figure 4-4. The newly created Photo Gallery project

A Little Project Cleanup

Now that you have created your project, you first have to do a little cleanup. Since this app will be built around a Page View Controller, you don’t need the default View Controller that was created with the project.

  1. To remove the default View Controller, first right-click (or Control-click) the ViewController.swift file in the Project navigator and select Delete, as shown in Figure 4-5, followed by Move to Trash when prompted.

    9781484217146_Fig04-05.jpg

    Figure 4-5. Removing the default View Controller

  2. Next, you need to select the Main.storyboard file and then select the View Controller scene as shown in Figure 4-6.

    9781484217146_Fig04-06.jpg

    Figure 4-6. Selecting the View Controller scene

  3. To delete the scene, either press the Delete key on your keyboard or choose Edit image Delete from the application menu.

    Now that the default View Controller has been removed, it is time to add the Page View Controller to the project.

Adding the Page View Controller

  1. Right-click (or Control-click) the Photo Gallery group in the Project navigator and select New File.
  2. Select Source under tvOS, then select Cocoa Touch Class, as shown in Figure 4-7.

    9781484217146_Fig04-07.jpg

    Figure 4-7. Adding a new Cocoa Touch Class to the project

  3. Click Next, select UIPageViewController from the Subclass drop-down list, and enter PageViewController as the Class name.
  4. Make sure Swift is selected as the Language (as shown in Figure 4-8), and click Next, followed by Create to add it to the project.

    9781484217146_Fig04-08.jpg

    Figure 4-8. Adding the new PageViewController class to the project

    Now that you have added the PageViewController class, you need to add a Page Content View Controller to the project to handle displaying the pages of images from within the Page View Controller itself.

  1. Right-click (or Control-click) the Photo Gallery group in the Project navigator to add another New File to the project, but this time, select UIViewController from the Subclass drop-down list and name the class PageContentViewController.

Adding Scenes to the Interface Builder Canvas

Now that you have added the PageViewController and PageContentViewController classes to the project, the next step is to add the associated scenes to the Main.storyboard file and associate them with your two new classes.

  1. First, select the Main.storyboard file from the Project navigator to view its empty canvas.
  2. Select the Object library in the Utilities area of Xcode and drag a Page View Controller onto the canvas.
  3. Select the Page View Controller and choose the Attributes inspector from the Utilities area and check the Is Initial View Controller check box (as shown in Figure 4-9) to indicate that this is the first view controller that will be loaded when the app is launched.

    9781484217146_Fig04-09.jpg

    Figure 4-9. Adding a new Page View Controller to the Main.storyboard and setting it as the Initial View Controller

    Image Note  In tvOS, the scenes within a storyboard are large, each the size of a full 1080p television screen. This can make it difficult to navigate a storyboard containing multiple scenes. To remedy this, you can zoom in and out of a storyboard by pressing Command + and Command –, respectively.

  4. Next, select Scroll from the Transition Style drop-down list instead of Page Curl (as shown in Figure 4-10) to cause the Page View Controller to show the Page Control with its horizontal white dots, as shown previously in Figure 4-1.

    9781484217146_Fig04-10.jpg

    Figure 4-10. Setting the Transition Style to Scroll

  5. Finally, with the Page View Controller scene still selected, select the Identity inspector in the Utilities area and set the Class to PageViewController, as shown in Figure 4-11.

    9781484217146_Fig04-11.jpg

    Figure 4-11. Setting the Page View Controller scene class to PageViewController

Now that you have added the Page View Controller scene to the Main.storyboard, you need to add an additional View Controller for the PageContentViewController class.

  1. Drag and drop a View Controller from the Object library onto the canvas underneath the Page View Controller scene.
  2. Select the new View Controller and set both the Class and the Storyboard ID to be PageContentViewController in the Identity inspector of the Utilities area as shown in Figure 4-12. (Setting the Storyboard ID of the Page Content View Controller will allow you to instantiate instances of it programmatically later on in the chapter.)

    9781484217146_Fig04-12.jpg

    Figure 4-12. Setting the Page Content View Controller scene class and Storyboard ID to PageContentViewController

    Now that you have the Page View Controller and Page Content View Controller scenes added to the Main.storyboard, you need to add the Image View to the Page Content View Controller to actually display the photos for our Photo Gallery.

    Image Note  Before adding the Image View to the Page Content View Controller scene, you will need to zoom back in again to 100% if you have previously zoomed out. The easiest way to do this is to hold down the Control and Command keys and press =. You can also right-click (or Control-click) anywhere on the empty blank space of the canvas and choose Zoom to 100%.

  1. Drag and drop an Image View onto the Page Content View Controller scene, as shown in Figure 4-13.

    9781484217146_Fig04-13.jpg

    Figure 4-13. Adding an Image View to the Page Content View Controller scene

Since you are going to want the Image View to fill the entire screen, you will want to add some auto layout constraints to the Image View to pin it to the edges of the Page Content View Controller.

  1. With the Image View selected, click the Pin Tool button in the layout bar at the bottom of the canvas.
  2. Uncheck the Constrain to margins check box.
  3. Select Items of New Constraints from the Update Frames drop-down list.
  4. Add the four constraints shown in Figure 4-14.

    9781484217146_Fig04-14.jpg

    Figure 4-14. Adding constraints to the Image View

Now that the Image View fills the entire Page Content View Controller, the last thing you need to do is create an outlet for the Image View in the PageContentViewController.swift file.

  1. Select the Page Content View Controller, and then click the Assistant editor icon

    9781484217146_unFig04-01.jpg

    to also open the PageContentViewController.swift file, as shown in Figure 4-15.

    9781484217146_Fig04-15.jpg

    Figure 4-15. Viewing the Page Content View Controller in the Assistant editor

  2. You may also want to hide the Utilities area temporarily by clicking the

    9781484217146_unFig04-02.jpg

    button in the top-right corner of Xcode to give yourself more room to work.
  3. Zoom the storyboard canvas back to 100% if zoomed out, and then right-click (or Control-click) and drag from the Image View to the first line within the PageContentViewController class definition to add a UIImageView outlet named imageView, as shown in Figure 4-16.

    9781484217146_Fig04-16.jpg

    Figure 4-16. Adding the imageView outlet to the PageContentViewController class

Now that the Image View is connected to the imageView outlet, the scene work in Interface Builder is complete. You can now re-select the Standard editor (by clicking the 9781484217146_unFig04-03.jpg icon in the top-right corner of Xcode) and turn your attention to adding the required data model structures to the project for the Photo Gallery app.

Adding the Photo and Album Data Model Structures

Since the purpose of a Photo Gallery app is to display a collection of photos, you are going to want to represent each of those photos using a custom data structure in order to keep things as clean and organized as possible. You are also going to create an Album structure to store a collection of related Photos. The completed app will allow the user to browse through an album of photos using the Page View Controller you have already created. So let’s get started!

First, let’s start by creating a Model group for these new structures under the Photo Gallery group in the Project navigator.

  1. Right-click (or Control-click) the Photo Gallery group, select New Group, and name it Model.
  2. Right-click (or Control-click) on the Model group and select New File.
  3. Select Source under tvOS and then select Swift File.
  4. Click Next and then name the file Photo.swift and then click Create.

Add the following code into the newly created Photo.swift file:

1       import Foundation
2
3       struct Photo {
4           var name: String = ""
5
6           init(name: String) {
7               self.name = name
8           }
9       }

This Swift Photo structure contains a single property, a String called name (Line 4), which will store the name of the photo associated with it.

Next, add another Swift File called Album.swift and add to it the code below:

    1      import Foundation
 2
3      struct Album {
 4          var name: String = ""
 5          var photos: [Photo] = []
 6
 7          init(name: String, photoNames: [String]) {
 8              self.name = name
 9              for photoName in photoNames {
10                  self.photos += [Photo(name: photoName)]
11              }
12          }
13      }

The Album structure also contains a String name property (Line 4) as well as an array of Photo structures called photos (Line 5) that make up the contents of the album.

The Album structure also has a designated initializer (Line 7) that takes in the name of an album as well as an array of photo name Strings. The array of photo name Strings is then used to create the photos array of Photo structures when the Album is initialized (Lines 9-11).

Adding the Photo Image Files to the Asset Catalog

Now that you have created the Photo and Album data model structures, next you are going to add the actual photo image files to the project.

The best way to add images to an Xcode project is by adding them to an asset catalog. Asset catalogs simplify the organization and management of images in your app. When you created the Photo Gallery project, a default asset catalog named Assets.xcassets was created automatically.

  1. To add the photo image files to the asset catalog, first click the Assets.xcassets folder in the Project navigator. By default, the Assets.xcassets contains an App Icon & Top Shelf Image folder, as well as a LaunchImage image, as shown in Figure 4-17.

    9781484217146_Fig04-17.jpg

    Figure 4-17. The default Assets.xcassets asset catalog

To add the photo image files to the asset catalog, first download the image files, as discussed in the Introduction to this book. After they have been downloaded and unzipped, simply drag and drop the Animals folder into the asset catalog set list, as shown in Figure 4-18.

9781484217146_Fig04-18.jpg

Figure 4-18. Adding the Animals folder of images to the asset catalog

Adding images to an asset catalog automatically copies the images to the project, so once they have been added, feel free to delete the original files you downloaded.

By default, when images are added to an asset catalog, they are added for All Universal devices, as shown in Figure 4-19. This means that a single image in an asset catalog can support multiple files at different resolutions (1x, 2x, 3x) for the various Apple devices available.

9781484217146_Fig04-19.jpg

Figure 4-19. By default, images added to an asset catalog are added for All Universal devices

You don’t need to support multiple resolutions as you are developing an Apple TV application, so for each of the images in the Animals folder, check the TV OS Apple TV check box, uncheck the All Universal check box, and then drag the image from the Unassigned spot to the 1x Apple TV spot, as shown in Figure 4-20.

9781484217146_Fig04-20.jpg

Figure 4-20. Reassigning all of the Universal images to Apple TV images in the asset catalog

Now that the photo image files have been added to the project, you can start filling in the details of the PageViewController and PageContentViewController classes. You are well on our way to finishing up this app!

Completing the Photo Gallery App

The only changes you have made to the PageContentViewController class up until this point was to add the UIImageView outlet earlier in the chapter. You still need to make a few more changes to complete the functionality of the Page Content View Controller.

After selecting the PageContentViewController.swift file from the Project navigator, add the following two lines to the beginning of the class definition:

1       var index: Int = 0
2       var photoName: String = ""

Since there will be multiple instantiations of the PageContentViewController class (one for each page in the Page View Controller), you will want each Page Content View Controller to keep track of both its page index (Line 1) and the name of its photo (Line 2). The Page View Controller will initialize these properties when it creates the Page Content View Controller.

Finally, add the following lines to the end of the viewDidLoad method:

1       if let image = UIImage(named: self.photoName) {
2           self.imageView.image = image
3       }

This initializes the Image View, loading in the photo represented by the photoName property that was set by the Page View Controller when it created the Page Content View Controller.

The final changes you need to make to complete the Photo Gallery app are within the main PageViewController class. Select the PageViewController.swift file in the Project navigator and have the PageViewController class adopt the UIPageViewControllerDataSource protocol by editing the first line of the class definition to match the following line of code:

1       class PageViewController: UIPageViewController, UIPageViewControllerDataSource {

Next, add the following properties at the beginning of the class definition:

1       var pageIndex: Int = 0
2       var album = Album(name: "Animals",
3                   photoNames: ["Cows", "Dog",
4                                "Horses", "Seagull", "Sheep"])

The pageIndex property (Line 1) keeps track of which page the Page View Controller is currently displaying, and the album property (Lines 2-4) is the Album structure that provides the Photos information to the Page Content View Controllers.

Next, add the following lines to the end of the viewDidLoad method:

1       self.dataSource = self
2       if let pageContentViewController =
3           self.pageContentViewController(self.pageIndex) {
4              self.setViewControllers([pageContentViewController],
5              direction: .Forward, animated: true, completion:
6              nil)
7       }

Setting itself as its own data source (Line 1) means that it has adopted the UIPageViewControllerDataSource protocol, and it will then be able to provide the data necessary to display the various Page Content View Controller pages. After setting the data source, you generate the initial Page Content View Controller (Lines 2-3) using the pageIndex property (which has been initialized to 0), and initialize the Page View Controller to display the new Page Content View Controller with a Forward navigation direction (Lines 4-6).

Now that you have identified the PageViewController as its own data source, you need to add the following methods required by the UIPageViewControllerDataSource protocol to the end of the PageViewController class definition:

 1      func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
 2          if let contentViewController = viewController as? PageContentViewController {
 3              return self.pageContentViewController(contentViewController.index - 1)
 4          }
 5
 6          return nil
 7      }
 8
 9      func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) ->         UIViewController? {
10          if let contentViewController = viewController as? PageContentViewController {
11              return self.pageContentViewController(contentViewController.index + 1)
12          }
13
14          return nil
15      }

When the user is swiping back and forth between pages, these two methods are called to provide the Page View Controller with the page that is before or after the current page, depending on whether the user has swiped backward or forward, accordingly. If there is no page before or after the current page (depending on which direction the user swiped), then the methods simply return nil.

Add the next two methods at the end of the class definition for the two UIPageViewControllerDataSource protocol methods, which provide the data needed to display the Page Control:

1       func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
2           return album.photos.count
3       }
4
5       func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
6           return self.pageIndex
7       }

The first returns the total number of pages for the Page View Controller, which in this case is the number of Photos contained within the Album. The second returns the current page index so that the Page Control knows which dot should be selected.

The final method you will add to the end of the class definition is the one that returns the instantiated Page Content View Controllers for a specified page index:

 1      func pageContentViewController(index: Int) -> PageContentViewController? {
 2          if let contentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageContentViewController") as?             PageContentViewController where index >= 0 && index < album.photos.count {
 3              self.pageIndex = index
 4              contentViewController.index = index
 5              contentViewController.photoName = self.album.photos[index].name
 6              return contentViewController
 7          }
 8
 9          return nil
10      }

If an invalid index is passed that is beyond the number of photos within the album, the method simply returns nil (Line 9). If the index is valid, then the pageIndex property is updated with the new index (Line 3) and a new Page Content View Controller is created (Line 2) and initialized (Lines 4-5) with the index and the photo name from the associated Photo in the Album before it is returned (Line 6).

That’s it! If you run the app by clicking the Build and run button in Xcode, it should run in the Apple TV simulator and display a full-screen image of a number of cows grazing, as shown in Figure 4-21.

9781484217146_Fig04-21.jpg

Figure 4-21. The completed Photo Gallery app

Using the Apple TV Remote in the Simulator will allow you to swipe between the five different photos from the Animals album. Tapping on the left and right sides of the remote will allow you to scroll through the images as well.

Summary

In this chapter you created a Photo Gallery app to view multiple high-resolution photo image files using a Page View Controller. This has given you a solid starting point for learning more about the different User Interface controls available in tvOS.

In the next chapter we are going to expand on the Photo Gallery app by adding the ability for the user to choose from a list of multiple albums, and then browse the photos within them. We are also going add a custom static Top Shelf image to further showcase the contents of the app from the Home screen of the Apple TV.

Exercises

  1. Try changing the Transition Style of the Page View Controller from Scroll to Page Curl and see what effect that has on the app. Try slowly swiping back and forth (and even up and down) to see how the Apple TV responds. Which style do you prefer?
  2. Try adding some of your own 1080p images to the project to make your own customized Photo Gallery app.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset