There seems to be no standard way of dealing with UIPickerViews. Sometimes they are attached right to the bottom of the interface and never move around (like in the built-in Clock application.) Other times they fly up from the bottom like the keyboard but are embedded in a UIToolbar or UIActionSheet.
I’ve come up with a way of dealing with UIPickerView controls that I kind of like. Here’s the gist:
- The UIPickerView hides and shows very similar to how the keyboard hides and shows.
- When the UIPickerView shows, the rest of the view (including the navigation bar) is dimmed.
- Tap anywhere in the dimmed area to hide the UIPickerView. The dismissal tap just dismisses the UIPickerView and won’t be picked up by the view in the background.
To do this we create a custom UIView whose only job is to dim the background and receive the dismissal tap. Once everything is wired up, we hide and show the picker with – (void)showPickerView and – (void)dismissPickerView. Easy!
Here’s why I like it:
- Dimming the background puts the UI focus on picking. You can still see the background and the context in which the pickerView showed up (and it can still change state depending on what has been picked in the view.)
- A “done” button, while unambiguous, would cover up precious screen real estate and is a smaller target to hit than a dimmed background.
- At least for me, tapping the dimmed background to dismiss feels very natural. The fact that the background is dimmed implies that my taps will not affect any of the controls and whatnot in the background.
I’ve created an Xcode project that has an example. Feel free to take a look and use this in your own projects. The comments should make everything clear. I tried to think of a way to make the whole thing more modular (perhaps implementing this all as a subclass of UIPickerView?) but the complexities of having views in the navigation controller and animating everything confused me. Maybe when I’m smarter…
If you find this useful, let me know.