How to present a view controller on top of a UISplitView Controller


Since its introduction in iOS 5, our good friend the UISplitView Controller has always had a really annoying habit: it has to be the root view controller in our apps. This means that it cannot be presented from any other view controller, nor can the split view controller present other view controllers.

This sucks because 99% of all apps probably need to present a user choice overlay at some point during the lifetime of an app. While some apps may get away with showing a Popover on iPad, many apps would be better off if we could present something like a proper form sheet as pictured in the image above. However, by Apple’s definition, that’s just not possible with the split view controller.

Or is it…?

In this screencast I’ll show you how to make it appear as if we could present another view controller over a UISplitView Controller. We’ll employ a bit of magic to create a great user experience, and it’s not really difficult either. The whole thing works on both iPhone and iPad with no extra work, and it works with apps in Slideover Mode too.

At the bottom of the article I’ll show you the code snippets to make this magic happen, together with a fully working demo project.


This content is for members only.

How to use Swift classes in Objective-C

It is possible to use Swift classes from Objective-C code (and vice versa) – but Apple’s documentation is a little cloudy (and verbose) on how to actually achieve this magic.

Here’s how it works.

I’m assuming we have a project written in Objective-C, but there’s a new Swift class that needs to be used and we want to access it from Objective-C code, with Objective-C syntax.

Preparing your Xcode Project

As soon as we add a Swift class to an Objective-C project, we’ll get an invitation from Xcode: “Shall I create a Bridging Header” it asks. Technically we don’t need this: it will be useful to do the reverse of what we want to do, i.e. make Objective-C code usable in Swift.

Agree to the friendly offer anyway, so both classes can access each other natively. It may come in handy for future use.

Screen Shot 2015-11-13 at 18.09.59

You’d think this is all the information our clever Xcode should need, but it isn’t. We’ll also need to tell it that we want to use both Swift and Objective-C in the same project (as if that wasn’t obvious).

To do this, head over to your target and find the Build Settings tab. We’re looking for an option called Embedded Content contains Swift Code (under Build Options):

Screen Shot 2015-11-13 at 18.50.20

That’s all we have to do in Xcode for now.

Continue reading

How to instantiate an NSManagedObjectContext in iOS 9

Prior to iOS 9, Apple would do the heavy lifting and setup a Core Data stack with certain templates. One of those methods was the custom initialiser for the managed object context in the AppDelegate.m file.

Since iOS 9 however, the standard init method is deprecated and we need to use a designated initialiser instead, called initWithConcurrency. This initialiser has been around since iOS 5, but up until now it was optional to use it.

Here’s what a typical custom initialiser for a managed object context looked like prior to iOS 9:

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;

Opening a project with a method like this now will give us a deprecation warning and we must use initWithConcurrency instead.

This means that we now have to make a choice about what thread our managed object context is initialised on: the main queue, or perhaps a special background queue we’ve created. Our choices are:

  • NSPrivateQueueConcurrencyType
  • NSMainQueueConcurrencyType

Unless you have a private queue, the previous default behaviour can be brought back with the latter option. Here’s what the updated method would look like:

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;

    // since iOS 9
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;

How to test if a Navigation Controller’s Back Button was pressed

Screen Shot 2015-11-10 at 11.33.31

Sometimes it’s helpful to know if the Back Button on a UINavigationController was pressed. For example, an app that has a Save button on the left could double-up the Back Button as a way to cancel the operation.

Since iOS 5 there’s a view controller property that we can check in viewWillDisappear: if isMovingFromParentViewController returns YES, the current view controller is about to be popped off the stack.

Call the following method in the view controller that’s currently on the navigation stack, and being presented by the navigation controller:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    // check if the back button was pressed
    if (self.isMovingFromParentViewController) {

        // do something here if that's the case
        NSLog(@"Back button was pressed.");

viewWillDisappear is called whenever our view controller is about to be dismissed, either by the navigation controller, or modally. We may not want anything to happen when the dismissal happens while this view controller was presented modally, so this check makes sure we only opt-in to the navigation controller’s Back Button presses.

Note that the property is only available inside the viewWillAppear and viewWillDisappear methods.

How to extract a UIImage from a video in iOS 9

Here are two ways to extract the first frame of vision and turn it into a UIImage. Both methods are from the generous Stack Overflow community.

Both methods make use to the AV Foundation framework. There’s no need to import it, UIKit will take care of it for us.

Video URLs can be obtained in many ways, one of which is from something like an image picker. You can grab the URL in its didFinishPickingMediaWithInfo delegate method:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    // dismiss the picker
    [self dismissViewControllerAnimated:YES completion:nil];

    // grab the video
    NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];

Now that we have a video URL, let’s see how we can extract a UIImage from it.

Continue reading

How to kill your app when it enters background mode

By default, any iOS app we create with Xcode automatically continues running for a short period of time, even if the user puts it in the background and launches a new app. You can even prolong the background execution of an app if your app needs it (for example, finish downloads or long running calculations).

But not all apps need this capability. In fact, if we want to be really nice, we can opt out app in to terminate when it hits the background. It’s really easy to do too: all we need to add is a boolean value into our Info.plist file. It’s called UIApplicationExitsOnSuspend.

Set it to YES and our app terminates as soon as someone presses the home button.

Screen Shot 2015-11-06 at 23.26.02

To add the key, either select your Info.plist file, or head over to your target and click the Info tab at the top (see screenshot).

This is a plist editor, and if you’re not familiar with how to use it, let me introduce you to one of the worst examples of UI design ever – Apple Style:

  • hover over the Key column until you see those little +/- icons come up
  • select the plus icon to add another row
  • double-click the Key part if your row until you can type something in
  • type “UIApplicationExistsOnSuspend” and see it turn into the text “Application does not run in background mode”
  • notice that the type column has changed into Boolean
  • in the Value column, on the far right, find two arrows and change the value to YES
  • that’s it!

Termination Testing

The easiest way to test if this is working is to add a couple of log messages to your AppDelegate file. Find the method stubs for applicationDidEnterBackground and applicationWillTerminate and write yourself a message:

func applicationDidEnterBackground(application: UIApplication) {

    NSLog("we are in the background...")

func applicationWillTerminate(application: UIApplication) {

    NSLog("we have terminated")

The first method will be called with or without the magic termination key. But the second method will only be called if the app is purged from memory. If you set the key correctly, both methods should be called.

Note that even though the app is killed, it is still visible when you double-tap the home key – but it no longer occupies any memory, nor will it continue to run in the background. As far as I know, this behaviour can only be changed by the user swiping up on an app after a double-tap, or by a hard reset of iOS (hold CTRL+HOME until the Apple Loog appears).