11
votes

I'm in the process of moving from hard-coded layouts to the new universal storyboard system available in Xcode 6. It's great to be able to create one storyboard that, through the magic of auto-layout, will work on both the iPhone and the iPad. And my understanding is that universal storyboards are backwards-compatible with iOS 7.

However, I'm running into a problem using popover segues. On iOS 8, the new 'Present as Popover' segue will display as a popover on an iPad interface and as a modal view controller on an iPhone interface. This is exactly the behavior I want, but when I run my universal storyboard on iOS 7, the app crashes whenever I attempt a popover segue. Here's the error message I get:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 
'-[UIPopoverController initWithContentViewController:] called when not 
running under UIUserInterfaceIdiomPad.'

This is a bit annoying, as I don't want to have to resort to separate storyboards for each UI idiom.

It looks like these are my choices:

  • Create a subclass of UIStoryboardSegue that will show a popover on iPad and a modal view on iPhone. This requires manually changing the class of all popover segues in my app.
  • Create two segues out of every bar button item, table cell, etc. - one that's a pure 'Popover' segue and one that's a pure 'Modal' segue. In this case, I'll be unable to just control-drag to the next screen and will have to create custom action methods that will invoke the right segue based on the current UI idiom.
    • Abandon universal storyboards and create device-specific storyboards until I can require iOS 8 from my users.

None of these are great alternatives, so I was wondering: do I have any other options? Am I missing any problems with my proposed solutions?

3
I'm having the exact same issue. At the moment I'm taking the custom segue route as I feel it's the least annoying, but I'm not very happy about it.Erik Tjernlund

3 Answers

1
votes

Xcode 6 supports unified storyboards. A storyboard can add or remove views and layout constraints based on the size class that the view controller is displayed in. Rather than maintaining two separate (but similar) storyboards, you can make a single storyboard for multiple size classes.

But Size classes are based on UITraitCollection which is supported on iOS8. That's why it's crashing on iOS7.

0
votes

I ended up making a modal segue and checking in code to see if it was on a iPhone with iOS 7. I then use performWithSegue to pick which segue should be taken. iOS 8 can handle the popover code but iOS 7 has issues.

-1
votes

Seems Like You are trying to present your view modally if device is iPhone and as Popover if the device is iPad.. To produce that the easiest way would be to check the InterfaceIdiom when the event occurs(like button click) and conditionally using appropriate approach.

-(IBAction)btnClicked:(id)sender{
    if([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad){
        //your popover code..
    }else{
        //your present modaly code...
    }
}