Swift Workshop 29: How to Use The iOS 8 Split View Controller – Part 3

Welcome to part 3 of the How to Use The iOS 8 Split View Controller workshop. Here’s what you learned so far:

In part 1, you learned the default behavior of the split view controller. In part 2 , you learned how I configured the SVCDemo app I created for this workshop series. As of now, the app basically, perform these tasks:

  1. Fetch flower names and images from the Flowers.plist file and dump them in an NSDictionary variable called tableDataSource. By the way, this dictionary is the primary view controller table view’s data source object.
  2. Display key-value pairs of the tableDataSource dictionary in the table view cells. As you already know, the dictionary’s keys are flowers names and their values are photo URLs.
  3. Pass the selected cell’s data to the detail view controller, which it display in its view’s image view and label control.

Now, in part 3 of the workshop series, you will learn how to do the following:

  1. Override the split view controller trait collection
  2. Show the primary view controller’s view by default
  3. Take the app for a spin

Override The Split View Controller Trait Collection

As you already know, scene 1 is connected to the ContainerViewController.swift class file, and scene 2 is embedded in scene 1’s Container. Figure 3-1 below shows this. So, to override the split view controller’s trait collection, you have to add code in scene 1’s class file. I will show you the source code to add in the class file first; then, I explain how it works.

svcdemo-figure3-1
Figure 3-1

Click the link below to download the ContainerViewController.swift file’s code. After unzipping the file, copy and past it in the SVCDemo app’s ContainerViewController.swift file. Figure 3-2 is an image of the file’s code and I’ll be referencing it from now on.

ContainerViewController.swift
svcdemo-figure3-2
Figure 3-2: Image of source code

How The Code Works

Code you entered in the viewDidLoad() function are user defined function statements. A user defined function is one that an iOS app developer implement in a class file; further more, a function should perform a specific task.

The performTraitCollectionOverrideForSize() function

This function’s job is to loop through the split view controller’s child view controllers and change each child view controller’s horizontal size class to Regular, only if child view controller’s screen size.width property is greater than its screen size.height. Since the performTraitCollectionOverrideForSize() function is used in the viewDidLoad() function, it is fired only once. That’s because the viewDidLoad() function itself, is fired only once. The performTraitCollectionOverrideForSize() function is also used in the viewWillTransitionToSize() function and that function is fired every time you rotate the simulator or a real device.

To verify when the performTraitCollectionOverrideForSize() function’s if statement code block is executed, add this statement below the for statement’s closing } bracket.

println("The device's screen size.width = \(size.width) and screen size.height = \(size.height)")

Once you’ve done that, run the app in any one of the iPhone or iPad simulator’s. If the function’s if statement evaluates to true, you will see output similar to this one, in Xcode’s Debugger window:

The device's screen size.width = 1024.0 and screen size.height = 768.0

For example, the first time you you run the app in the iPhone 4s simulator, you won’t see the println() function’s message in Xcode’s Debugger window; however, ever time you rotate the simulator to landscape orientation, above println() function’s message is shown in Xcode’s Debugger window. Now, take a look at Table 1 below, it list all of the iPhone and iPad screen size.width and screen size.height values in portrait and landscape orientation. As you can, the performTraitCollectionOverrideForSize() function’s if statement code block will only run for landscape orientation screen size.width and size.height values.

Device Screen Size
iPhone 4s portrait orientation:

  • size.width = 320.0 points
  • size.height = 480.0 points

landscape orientation:

  • size.width = 480 points
  • size.height = 320 points
iPhone 5/5s/5c portrait orientation

  • size.width = 320.0 points
  • size.height = 568.0 points

landscape orientation:

  • size.width = 568 points
  • size.height = 320 points
iPhone 6 portrait orientation

  • size.width = 375.0 points
  • size.height = 667.0 points

landscape orientation:

  • size.width = 667.0 points
  • size.height = 375.0  points
iPhone 6 Plus portrait

  • size.width = 414.0 points
  • size.height = 736.0 points

landscape orientation:

  • size.width = 736.0 points
  • size.height = 414.0 points
iPad2, Air, Retina portrait orientation:

  • size.width = 768.0 points
  • size.height = 1024.0 points

landscape orientation:

  • size.width = 1024.0 points
  • size.height = 768.0 points

The configureSplitVC() function

This function creates a split view controller object called spitVC and configure three of its properties. The first property configured is the splitVC object’s delegate. It was set to the ContainerViewController class and it is referred to as self. The reason why we configured this property of the splitVC object is so that delegate functions of the UISplitViewControllerDelegate protocol implemented in the ContainerViewController class will work. By the way, notice how the ContainerViewController class conforms to the UISplitViewControllerDelegate protocol, on line 11, in Figure 3-2 above.

The second property configured is the splitVC object’s preferredDisplayMode. As you can see on line 41 in Figure 3-2 above, the preferredDisplayMode property was set to the AllVisible value, which means that both the primary and the secondary view controllers will be visible at the same time.

The third and final property configured is the splitVC object’s preferredPrimaryColumnWidthFraction. As you can see on line 42 in figure 3-2 above, it was assign the fractional value 0.4; this number specifies the width of the primary view controller’s view. Increasing the fraction make the view wider; the opposite is true when you decrease the number.

The viewWillTransitionToSize() function

This is a delegate function of the split view controller class and its job is to notify the container that the size of its view is about to change. At this point, we called the performTraitCollectionOVerrideForSize() function. As you already know, that function override a child view controller’s horizontal class to Regular. Further more, the parent of the child view controller is the split view controller.

Show The Primary View Controller’s View By Default

By default the secondary view controller’s view is the one shown by default, every time you launch the application. To make the app show the primary view controller’s view instead, you implemented a delegate function of the split view controller class. It is called splitViewController collapseSecondaryViewController ontoPrimaryViewController(). It does exactly what its name says-collapse the secondary view controller (DetailsViewController) onto the primary view controller (PhotosViewController). By default, it returns false. We changed it to return true; thus making the primary view controller’s view the first one shown, every time the SVCDemo app is launched.

Take The App For A Spin

Now that you know how the ContainerViewController.swift class file’s code work, you should test drive the application in the iPhone and iPad simulator’s to see result of the code. The first screen shot below shows what the split view controller’s primary view look like in portrait orientation, by default on the iPhone 6 simulator. The second screen shot shows what the split view controller’s views look like on the iPhone 6 simulator, when you click a row, then rotate the simulator to landscape orientation.

svcDemo-figure3-3 svcDemo-figure3-4
Figure 3-3 Figure 3-4

This is the end of part 3 of the tutorial. Next week, I will bring you the final part of the tutorial. In the mean time, comments are welcomed! 🙂