Making a custom back button in iOS without any pain

Creating a custom back button has always been a pain in iOS. The default iOS back button has the title of the previous screen, which is generally inconvenient. You can’t set the back button title directly in viewController with that option. Generally, you don’t even need a back button title at all (as most designs just have a custom back button image), but to remove that title you need to do something to the previous screen title. And let’s not even begin to talk the about image stretching we suddenly got in iOS8.

There is one solution though, which has proven to be a good one: create a custom back button, using navigationItem.leftBarButtonItem in ParentViewController, that triggers navigationController?.popViewControllerAnimated(true). That way, we don’t really use system back buttons at all, so we don’t have their associated problems. It also allows us to make custom back button actions when we need those.

In trying to generalise all possible back button requirements into one piece of code here’s what I came up with:

Here we have LeftItem enum of all possible back buttons. Default leftItem is .backGeneral, which is described in the createBackButtonGeneral() function. You can change that according to your application design. So to have the default back button, you just need to subclass all your view controllers with ParentVC.

If you want some other back button (a menu button maybe?) on some of your screens, you can add that one to the enum in ParentVC, or just set the leftItem property to LeftItem.backSystemDefault and add a custom left button as you would do normally.

You could also use other enum options in the same way. You can use it to create a back button for modal transition too:

The only downside of this solution is that not every screen in your app uses your ParentViewController. Namely, default UI screens such as image pickers or contacts. We could still use the default approach to set a back button image in those, like this:

Then, call it in AppDelegate, in the func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool method. This will help to avoid possible issues.

Another solution is to add our custom back button to newly created screens manually before we show those screens, like this: