In the comments to my last post, a few things were pointed out by readers.
First and foremost was that by changing the spin duration of the picker view, when a user manually moved a component, it would take five seconds to settle into its new position. Well, that's no good.
Here's a new version that resolves that issue.
Unfortunately, as far as I could tell, there is no way to get the picker view to change the spin duration during the run. You can return conditional values in the method, but the picker view never checks for changed values after it loads. My solution is a bit of a hack, but it works. There are two picker views - a normal one, and one using the longer-spinning subclass. They use the same data source and delegate and show the same data. When one changes, the other changes as well. The user interacts with the normal one, but when the shake or press the Spin button, the short one is hidden and the long one is unhidden, then after the spin, the long one is hidden and the normal one is unhidden. The user never sees the change, but now the behavior is correct in both manual and automatic situations.
Now, one thing to note here - A single view can't be shown on the screen twice. Currently, I have two sets of the arrays holding the data, one for each picker view. I think it might be possible to use a single one by manually having the picker views reload their data when they are unhidden, but for now, this works.
The other thing that was pointed out to me in the previous comments is that UrbanSpoon doesn't actually do anything anywhere near this complex. They use images to simulate the spinning using animation. That's a fine approach, but given the memory constraints of the iPhone and the leakiness of UIImageView animation on at least some versions of the SDK, I think I would do it this way and avoid using five megs or so worth of pre-rendered animations.