Tag Archives: UINavigationController

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:

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 test which class presented a UIViewController

The NSObject class has an interesting method called isKindOfClass. As the name suggests it lets you test what kind of class it belongs to. As everything we use inherits from NSObject, this method is available in our own classes we use in iOS and Mac development.

This method can come in handy for example when three different classes present the same view controller and you’d like to make decisions based on which controller has presented your content. Consider the following two example.

If you present a UIViewController via a modal segue you can test which class the presenting view controller belonged to like so:

If however your view controller was presented via a UINavigationController then the above isn’t going to work. Instead you need to check which view controller was on the navigation stack previously.

Here’s how to do this:

How to attach custom actions to an Edit Button Item (or The Dark Secrets of the Edit/Done Button)

You can create an editButtonItem in a UITableViewController like this:

If your view controller is embedded into a navigation controller, an edit/done button will show up and you can toggle its state by pressing it.

Edit-Done

That’s great, but it takes a deeper understanding of how this happens to make full use of it in your own projects.

What this button actually does is set the “editing” property of your view controller to YES or NO. If it’s YES, the button turns into “Done” (and equivalent translations), and if it’s NO then it turns into “Edit”. You won’t notice this on a standard view controller, but on derivatives (such as a UITableViewController) this has a substantial effect: the table view enters edit mode and changes appearance.

You can therefore test the state of the button by querying your view controller:

But that’s not an action, that’s just a test. If you’d like for something to happen when that edit button is pressed, you must override the following function which is called every time that button is pressed:

This method is called by the table view when that button is pressed. We’re calling the super method first, then add our own bits at the end. You can also call this method from anywhere and put the table view into or out of edit mode like so:

How to turn the Navigation Bar in iOS 6 opaque when compiling with Xcode 5

Xcode 5 is nice… but it has habits that drive me up the wall. For example, no matter which Base SDK you compile with, your Navigation Bars will always look translucent – no matter how hard you try to avoid this in the Storyboard, and no matter which iOS Version you deploy to.

Would have never happened under Xcode 4. But I suppose we must go with the times.

All we can do is to turn it opaque in code – and if we’re not using black, at least give iOS 7 a tint of your selected colour at the same time. This method will take a UINavigationController and change its colour:

Note that on iOS 7 your navigation bars are always translucent, I haven’t found a way to change this. All you can do is “tint” those. The above code will however bring opaqueness back into your apps when running on iOS 6.

How to set the colour in a UINavigationBar

Since Xcode 5 and iOS 7 the default appearance of a UINavigationBar is black translucent. This even affects the same app running in iOS 6. Black opaque is deprecated and can no longer be set in Interface Builder.

However, you can set the appearance for all nav bars by putting this little gem in your App Delegate’s didFinishLaunchingWithOptions method:

You can specify colours other than black.

Note that iOS 7 devices are affected differently by this change: only the icon/text colour will change into your specified colour, but the bar itself will remain translucent. Using black means text buttons are barely readable. Hence, a version check would be appropriate:

How to hide a UIBarButtonItem in your Navigation Controller

Since UIBarButtonItems do not have a “hidden” property, we can’t just set this to yes and it’ll disappear. Instead, we can set them to nil.

In this example we’re hiding the right item in the navigation controller: