iPad Simulator crashes if a UIDatePicker is in a UIPopoverController

Just had one of those afternoons, where you waste 2 hours trying to debug some really strange crash in fairly simple code only to find that the API is at fault.

I have a UIDatePicker which I present in a (custom) UIAlertView used on the iPhone.   On the iPad it makes sense to use a UIPopoverController.

However on use, it would crash about 20% of the time on the first showing, and 100% of the time on the second with various errors like:

*** -[_UIPickerViewSelectionBar lastClickRow]: unrecognized selector sent to instance 0x5570c80

and

*** -[_UIOnePartImageView lastClickRow]: unrecognized selector sent to instance 0x5576b70

and

*** -[NSCFString lastClickRow]: unrecognized selector sent to instance 0x6081770

Basically it’s just sending “lastClickRow” to junk…
And now… what cost me 2 hours but you get for free (hey why not check out GPS Log ;)

The workaround:  Set the UIViewController’s .view (to the view containing the UIDatePicker) AFTER you call presentPopoverFromRect on the UIPopoverController.

No visual glitches with the workaround.

Thanks A  ._.

I could file a bug report… but I can’t stand that the iPhone bug reports are hidden, i.e. I have no idea if 100s of others haven’t already filed the same one and I may just waste my time.  Already kinda regretting the waste of time on this issue.


12 comments on “iPad Simulator crashes if a UIDatePicker is in a UIPopoverController

  1. Hi,

    Could you explain more on the workaround with a few lines of sample code?

    I encountered exactly the same problem, and can’t find a solution to it. When you say “Set the UIViewController’s .view (to the view containing the UIDatePicker) AFTER you call presentPopoverFromRect on the UIPopoverController.”, which UIViewController did you refer to?

    Thanks a lot.

  2. What I mean is this (exact code from GPS Log):


    [popoverController presentPopoverFromRect:popoverRect inView:showInView permittedArrowDirections:(UIPopoverArrowDirectionUp|UIPopoverArrowDirectionDown) animated:YES];
    contr.view = pickerView;

    where pickerView is the view containing your picker, and contr is the view controller that it should belong to.

    In other words, present the pop-over with a UIViewController that has an empty view. *then* you immediately set that view to the real view you want to display.

    Hope that helps :)

  3. I too had a tough time getting through this problem but at last got it resolved.
    Instead of adding UIDatePicker in interface builder, add it dynamically or programatically. It surely worked for me and hope that it works for you too.
    UIDatePicker *_datePicker=[[UIDatePicker alloc] initWithFrame:frame];
    [self.view addSubview:_datePicker];

  4. I’m having the same problem, and I haven’t been able to fix the problem after following the suggestions listed here. Can you help? I am doing the following to bring up the picker. It worked fine 3 months ago when I released it, but now I’ve come back to it (after some emails from customers) and I always get the crash you mentioned in the simulator as well as device :

    DatePickerViewController *viewController = [[DatePickerViewController alloc] initWithNibName:@”DatePickerViewController” bundle:nil];
    viewController.delegate = self;

    UINavigationController *navcontrol = [[UINavigationController alloc] initWithRootViewController:viewController];
    UIPopoverController *aPopoverController = [[UIPopoverController alloc] initWithContentViewController: navcontrol];

    [aPopoverController presentPopoverFromRect:[cell frame] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    aPopoverController.delegate = self;
    self.datepop = aPopoverController;

    // releasing stuff

  5. zs,

    You should initialise UINavigationController with a blank (new) UIViewController.

    AFTER you present the popup, set the viewController of the UINavigationController to be the “real” one (i.e. one containing the date picker).

  6. Thanks. I tried that but it wasn’t working for me. I tried adding the date picker programatically to the view instead of using IB, as someone suggested above, and it worked! I had tried that before but forgot to delete the date picker from the xib as well. But weird how something like this worked before with 3.2, but just broke with iOS4, and we have to come up with some hacky way to get around it.

  7. Glad you got it working. I wasn’t using the IB, so that is why I didn’t notice this.

    So the current advice is:

    1) Create the UIDatePicker programmatically (don’t use the IB)
    2) add it to the view *after* the popup is shown.

  8. My App, Direct Report was just reported as having this same problem. A helpful customer let me know it was crashing on the button. Thanks for the help guys!

  9. This is such a cheesy solution, I can’t believe I didn’t think of it myself. You’ve inspired me to have less respect for the API, and more respect for working code.

    Anyway, this same problem happens with ANY UIPickerView and a lot of other components too. Your solution, to load up the real view right after `presentPopover` and to reload a dummy view on `popoverControllerDidDismissPopover` worked perfectly. THANK YOU for writing this blog post.

  10. You’re welcome. It’s wise to have some suspicions for this API I have found, this is certainly not the first API crashbug I have found (MKMapView seems particularly buggy).

    The big clue here is the same selector being sent to a bunch of different objects – these objects are probably occupying the memory where the UIDatePicker used to be.

    Enabling NSZombieEnabled (just google it) is useful to track down these odd crashes.

  11. Your blog is really cool to me and your subject matter is very relevant. I was browsing around and came across something you might find interesting. I was guilty of 3 of them with my sites. “99% of site managers are guilty of these five mistakes”. http://bit.ly/uEMWS2 You will be suprised how fast they are to fix.