iOS 7 Popover Controller crashing under xcode 6

341 Views Asked by At

Whenever I try to use a UIPopoverController on iOS7 my app crashes. As far as I know, this is a recent issue and only occurs when built in Xcode 6. I don't have an iOS 7 iPad for testing but I have received info from Crashlytics that someone is experiencing this crash. It also crashes in the 7.1 simulator.

Any help, greatly appreciated.

Cheers

My code that crashes, within prepareForSegue::

if ([[segue identifier] isEqualToString:iPadiOS7ColorPickerSegue])
{
    FCColorPickerViewController *colorPickerVC = [segue destinationViewController];
    colorPickerVC.delegate = self;
    colorPickerVC.isPopover = YES;
    self.popVC = [(UIStoryboardPopoverSegue *)segue popoverController]; // <-- This line
}

The error, note the UIStoryboardPushSegue even though it is set as a Popover in the storyboard.

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '-[UIStoryboardPushSegue popoverController]: unrecognized selector sent to instance 0x7a1dd9a0'

Storyboard segue properties

EDIT

I have the view controllers set up in a unified storyboard. This code was working, however after my latest update using Xcode 6 I started receiving crash reports for this error.

It appears that my segue selection is not being respected as it seems to call UIStoryBoardPushSegue.

3

There are 3 best solutions below

0
On BEST ANSWER

Instead of calling a segue, I ended up assigning the laid out view controller I was trying to present as a popover, a Storyboard Identifier. I could then use this as the contentViewController for a popoverController. (I would not have access to [segue destinationViewController], as I am no longer displaying it as a segue)

The Push segue on iPhone, iOS7 seems unaffected so I have left it unchanged.

I had to make the (UIPopoverController*) popVC property strong so as it retains a reference, then I free it when it is dismissed.

Below is the code I use to check for iOS version and device and where the segues where called from.

if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)]) {
    // conditionally check for any version >= iOS 8 using 'isOperatingSystemAtLeastVersion'
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        [self performSegueWithIdentifier:kiPadiOS8ColorPickerSegueID sender:nil];
    } else {
        [self performSegueWithIdentifier:kiPhoneiOS8ColorPickerSegueID sender:nil];
    }
} else {
    // we're on iOS 7 or below
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        //[self performSegueWithIdentifier:kiPadiOS7ColorPickerSegueID sender:nil];

        FCColorPickerViewController *colorPickerVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"ColorPickerPopover"];// = [ destinationViewController];
        colorPickerVC.delegate = self;
        colorPickerVC.isPopover = YES;

        self.popVC = [[UIPopoverController alloc] initWithContentViewController:colorPickerVC];
        [self.popVC presentPopoverFromRect:CGRectMake(0, CGRectGetHeight(self.view.frame) - 50, CGRectGetWidth(self.view.frame), 50) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

    } else { // iPhone, iOS 7
        [self performSegueWithIdentifier:kiPhoneiOS7ColorPickerSegueID sender:nil];
    }

}
1
On

Try this :

// write code in .m class

UIPopoverController *PopoverController;

-(void)dealloc
{

    if(self.PopoverController)
    {
        [self.PopoverController dismissMenuAnimated:NO];
    }

}
0
On

I know its late but I hope this solution will help the others. I am using it on my projects and its working. Add following method to your code to make it working for iPhone as well:

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{ 
if ([identifier isEqualToString:iPadiOS7ColorPickerSegue] && IS_IPHONE) {

   FCColorPickerViewController *colorPickerVC = [self.storyboard instantiateViewControllerWithIdentifier:@"FCColorPickerViewController"];
colorPickerVC.delegate = self;
colorPickerVC.isPopover = YES;
 [self presentViewController:colorPickerVC animated:YES completion:NULL];

    return NO;
}

return YES;

}