Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I support a split view in landscape on the iPhone 6 or 5s?

In my app there's a lot of wasted space in landscape on the iPhone 6, and to a lesser extent even on 4" screens. I'm already using iOS 8's UISplitViewController changes to support the two-pane view in landscape on the iPhone 6 Plus, but it'd be useful to see both panes on some smaller devices as well.

Conveniently Apple had a WWDC 2014 session, "Building Adaptive Apps with UIKit" which included details on exactly how to do this. You can download the sample code here, but in short: they put the UISplitViewController inside of a UIViewController subclass. The subclass uses setOverrideTraitCollection:forChildViewController: to force [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular] on the split view when it considers the width wide enough. At the time the sample code worked well, and still does on most devices.

However after attempting to use this code in my own app, I discovered it fails horribly on the iPhone 6 Plus. You can see this yourself if you download the sample code and make two changes:

  • Add a storyboard, add an empty view controller to that, and set it as the "Launch Screen File". This is necessary to run the app at its native resolution on the 6 Plus.
  • In AAPLTraitOverrideViewController.m, change line 21 to size.width > 500.0, or anything greater than 414. This is necessary to ensure the split view only shows a single view in portrait on the 6 Plus.

Now you can run the app in the simulator. To see the problem, just do this:

  • Rotate the device to landscape (command-right arrow)
  • Rotate it immediately back to portrait (command-left arrow)

You can already see that something's not right. All of the table cells should have an arrow on the right side in portrait, but they don't. They're behaving like they're still in a split view. If you tap one of those rows, it gets worse—the detail view slides up from the bottom, and the navigation bar is gone.

I think there must be a bug in iOS 8 here that's causing the problem. But since this code was shared before the iPhone 6 Plus was announced, it also seems possible that it just needs some adjustments to make it compatible with that device. So far the only solution I've found is to change line 21 to something like if (size.width > 500.0 && size.width < 736.0) but I don't want to use code that could break again the next time Apple introduces a new screen size. Is there a better way to handle this?

like image 310
robotspacer Avatar asked Sep 25 '14 00:09

robotspacer


People also ask

Does iPhone 6 have split screen?

It is quite easy to activate this Split Screen mode on your iPhone 6 Plus or iPhone 6s Plus; just turn your iPhone on its side and it splits the content side by side. This might remind you of your iPad or Mac screen.


1 Answers

Seems like you'll always want to make the horizontal size class regular (UIUserInterfaceSizeClassRegular). To do this, override traitCollectionDidChange:. In this method, if the vertical size class is compact (suggesting it's likely in landscape), override the trait collection so that the horizontal size class is regular.

UITraitCollection *compactHeight = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
if ([self.traitCollection containsTraitsInCollection:compactHeight]) {
    UITraitCollection *regularWidth = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
    self.forcedTraitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:@[self.traitCollection, regularWidth]];
    [self setOverrideTraitCollection:self.forcedTraitCollection forChildViewController:_viewController];
} else {
    [self setOverrideTraitCollection:nil forChildViewController:_viewController];
}

However, if you'll want more specific behavior, you'll have to rely on canvas size for app-specific behavior.

like image 157
Matt Zanchelli Avatar answered Sep 23 '22 04:09

Matt Zanchelli