UIKit sets first responder to nil, making it impossible to send -undo: (and other actions) to appropriate targets

In our applications, we have an Undo button in our main view controller’s navigation bar. This button is supposed to do two things:

  • If there is a text field being edited, it should undo in the text field’s undo stack.

  • Otherwise, it should undo in the document’s undo stack.

Unfortunately, dismissing the keyboard clears out the window’s first responder, which means the -undo: message never makes it to the view controller.

[Read more…]

How I’d improve the UIScrollView.contentInset API

UIScrollView.contentInset is conceptually a very simple API: it extends the scrollable range beyond that implied by the contentSize property. (The objc.io magazine has a great article on UIScrollView that explains contentInset in terms of simple arithmetic.) Its two main use cases are avoiding the keyboard and correctly underlapping iOS 7+’s translucent bars. But if you want to get more complicated than a navbar and a keyboard, the simple nature of contentInset makes things difficult.

[Read more…]

A Cascade of Table View Bugs

Yesterday I wrote some code to hide the Trash location in our document picker when it’s empty. Today, I got a bug report that attempting to add or remove a cloud storage location in the document picker would now crash with an exception thrown by UITableView. These didn’t sound all that related other than timing and both involving the document picker.

And at first, all the evidence told me they were not related. But thanks to a combination of overlapping bugs it took me over an hour, a fair bit of disassembly, and some moral support from my coworker Jake to track down the origin of the bug.

[Read more…]

Implementing -[UIApplication targetForAction:to:from:]

Updated: It turns out that UIKit likes to set the first responder to nil. At that point, my technique for finding the first responder winds up returning the UIApplication instance, which nullifies the technique. I’ve rolled back this change from our codebase; I’ll leave the blog post here, but I can’t advise anyone adopt this technique.

One of the best patterns that UIKit inherited from its older brother is the responder chain. It is a fantastic way to decouple UI controls from their targets and enables the same control to perform its function even as the user interface or controller layer changes around it.

On iOS, like on the Mac, UIApplication plays a central role in dispatching events to the responder chain: -[UIApplication sendAction:to:from:forEvent:] starts with the first responder and walks up the chain to find an object that can handle the provided action. But what if you just need to know whether such a responder exists, or you need to ask it further questions before you dispatch the action?

[Read more…]

UIPresentationController is (currently) a deficient API

iOS 8 brings a new and welcome class to UIKit: UIPresentationController, which reifies the presentation of view controllers in a configurable object whose lifetime can also be used to more cleanly manage auxiliary UI elements associated with that presentation.

Conceptually, popovers are a form of presentation, so they are now managed via a subclass of UIPresentationController, logically named UIPopoverPresentationController. Unfortunately, the actual API design surrounding this class leaves a lot to be desired.

[Read more…]

-targetViewControllerForAction:sender: is smarter than it seems

The new -[UIViewController targetViewControllerForAction:sender:] method (and its related methods, -showViewController:sender: and -showDetailViewController:sender:) in iOS 8 takes a clever responder chain-based approach to showing view controllers in a size-class-adaptable way.

Basically, all UIViewController instances respond to -showViewController:sender: and -showDetailViewController:sender:, but their implementations use -targetViewControllerForAction:sender: to find the appropriate view controller to actually do the showing. In the case of -showViewController:sender:, this is likely an enclosing UINavigationController, and in the case of -showDetailViewController:sender:, this is likely an enclosing UISplitViewController.

[Read more…]

WWDC Suggestions

If you’re going to WWDC, and prefer to avoid chain restaurants, Irish pubs, and Starbucks coffee, I’ve assembled a Foursquare list of personal recommendations. I might add to this list over time, so saving the list to your own Foursquare account will keep it up to date.

And if I personally know you, please friend me on Foursquare and share your suggestions with me. I’ll add your recommendations to my list of suggestions from others!