How can Xcode 6 adaptive UIs be backwards-compatible with iOS 7 and iOS 6?

Xcode6Adaptive Ui

Xcode6 Problem Overview


I just watched the WWDC video #216, "Building Adaptive UI with UIKit."

At about 45:10 Tony Ricciardi talks about changes to IB in Xcode 6 to support the new changes.

He says "You can deploy these documents backwards to older versions of iOS".

(where "These documents" presumably means XIBs and storyboards that have specific settings for different size classes.)

I'm not making this up. Go watch the WWDC video.

How is that possible? Trait collections and size classes are only defined in iOS 8. How can runtime behavior that's dependent on UI constructs that are new to iOS 8 work in previous iOS versions?

If it is possible it would be wonderful. You could build apps that will run on iOS 6, 7, and 8, and take advantage of the new flexible UI layout abilities that Apple has added to Xcode 6. I've created adaptive UI logic myself in code, and it's quite a bit of work.

Xcode6 Solutions


Solution 1 - Xcode6

Changes made to the UI with Size Classes in Interface Builder DO appear correctly on iOS 7 devices and the Preview in Xcode. For example, I changed some Auto Layout constraints and font sizes for Regular height Regular width and those changed constraints are visible in the iPad Simulator running iOS 7.0.

All size class optimizations are made available to iOS 7, except size classes that have a Compact Height. This has been confirmed by Apple and is now stated directly in the documentation:

**For apps supporting versions of iOS earlier than iOS 8, most size classes are backward compatible.

Size classes are backward compatible when:

  • The app is built using Xcode version 6 or later
  • The deployment target of the app is earlier than iOS 8
  • Size classes are specified in a storyboard or xib
  • The value of the height component is not compact**

Because iOS 7 doesn't respect a couple of size classes, if you use them you'll run into issues. For example: When you have Compact w Any h defined and then Compact w Compact h defined, on iOS 7 it will respect the Compact w Any h but on iOS 8 it renders the Compact w Compact h appearance.

So, if you would like to utilize those two size classes and maintain compatibility with iOS 7, I would do any optimizations you desire for iPhone in landscape in Any w Any h or Compact w Any h, then perform your other optimizations for different size classes as necessary, and that way you won't need to use any size class with compact height and will avoid running into issues.

Solution 2 - Xcode6

When deploying your app to iOS 7, Xcode will compile your storyboard in two different ways:

  • For iPhone, your storyboard gets compiled as "Compact-Regular" (Compact width, regular height), and this gets packaged as your "~iphone" nib.

  • For iPad, your storyboard gets compiled as "Regular-Regular" and gets packaged as your "~ipad" nib.

So if you're looking to deploy to both iOS 7 and iOS 8, you should focus your design on the Compact-Any and Regular-Any size classes. That will give you the best experience in terms of matching the UI across deployment targets. You are, of course, welcome to modify the layout for other size classes, but unless those modifications would get applied to the Compact-Regular or Regular-Regular size classes, then you would not see those modifications on iOS 7.

Solution 3 - Xcode6

Note: This answer was relevant to a beta version of Xcode 6 and is no longer applicable to the shipping version. See answers by Joey and Dave DeLong on this page for proper information.

(original answer retained below):


While Storyboards/XIBs configured to use size classes will run on iOS 7, the OS does not currently respect those size classes and appears to use the default 'Any/Any' size class.

I agree that the particular slide you are referring to seems to promise such compatibility, but it doesn't appear to be the case currently (Xcode 6 beta 2).

To test, I created a project (iOS 8 SDK, deployment target of 7.1) with a single button that is centered vertically and horizontally in the Any/Any size class, but aligned to the top left corner in the Compact/Compact size class (e.g. iPhone in landscape). Xcode's Preview Assistant shows that the button changes its position in iOS 8, but not iOS 7. I confirmed this behavior on an iOS 7 device as well.

Solution 4 - Xcode6

As some of the answers and comments were discussing the nature of backwards-compatibility, I thought I would share an excerpt direct from the [Apple Documentation][1]:

#Deploying an App With Size Classes on Earlier iOS Versions

**For apps supporting versions of iOS earlier than iOS 8, most size classes are backward compatible.**

Size classes are backward compatible when:

 - The app is built using Xcode version 6 or later
 - The deployment target of the app is earlier than iOS 8
 - Size classes are specified in a storyboard or xib
 - **The value of the height component is not compact**

~~~~~<br/><br/>
That last bullet point is targeted at this discussion, where Apple confirms that **as long as "compact height" is *not* used**, it should maintain backwards-compatibility.

Hope this helps someone! 


  [1]: https://developer.apple.com/library/ios/recipes/xcode_help-IB_adaptive_sizes/chapters/DeployingSizeClassesonEarlieriOSVersions.html#//apple_ref/doc/uid/TP40014436-CH13-SW1

Solution 5 - Xcode6

While dealing with the similar issue I found another answer that I haven't seen here yet. Looks like Size Classes in XIB files are not working at all. If I create cell prototype in the storyboard file it works in iOS7 as explained in other answers, however when the same prototype cell is moved into separate XIB file - size classes are ignored in iOS7.

Here is link to the sample project demonstrating this behavior: https://dl.dropboxusercontent.com/u/6402890/testSizeClasses.zip

In the prototype cell I have four constraints from each edge of the grey view. Each of the is configured in a same way: Any/Any - 10, Regular/Regular - 20

enter image description here

It works fine in iOS8 simulator for both XIB and Storyboard, and in iOS7 only cells defined in Storyboard gets updated constraints on iPad:

enter image description here

Solution 6 - Xcode6

If it saves anyone time, I believe that the way Xcode 6 provides quasi-backwards compatibility for size classes is via the historical ~ipad and ~iphone suffixed storyboards, and nothing more. This makes sense since size classes are a more abstracted way of how we previously defined an iPad storyboard, and an iPhone storyboard.

Therefore:

  • If your goal is to use size classes to support device family specific layouts (iPad vs. iPhone), then you are in luck: size classes are a nicer interface to the previously supported method.

  • If your goal is to use size classes to support altered layouts for different models within the same device family - ie. iPhone 5/6/6+ inc. landscape, then you are out of luck. Using these would require a minimum iOS 8 deployment target.

Solution 7 - Xcode6

@lducool - In interface builder, in the Identity inspector, change 'Builds For' to iOS7.1 and later.

Solution 8 - Xcode6

Unfortunately the answers from Dave and Joey do not work for me. I am not allowed to comment in this thread, so please forgive me if this is the wrong place.

I have made up a specific question for that: https://stackoverflow.com/questions/26694627/example-for-iphone-portrait-landscape-adaptive-ui-which-is-backwards-compatible

From what I learned so far, I believe now that, like in my example, is is not possible to have 2 separate, different constraints for one ui element in portrait and landscape mode with iPhone iOS7 based on size classes. Would be glad if I am mistaken, though.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDuncan CView Question on Stackoverflow
Solution 1 - Xcode6Jordan HView Answer on Stackoverflow
Solution 2 - Xcode6Dave DeLongView Answer on Stackoverflow
Solution 3 - Xcode6remmahView Answer on Stackoverflow
Solution 4 - Xcode6radiovisualView Answer on Stackoverflow
Solution 5 - Xcode6shaView Answer on Stackoverflow
Solution 6 - Xcode6Jonathan CrookeView Answer on Stackoverflow
Solution 7 - Xcode6Ash RView Answer on Stackoverflow
Solution 8 - Xcode6Tom MajorView Answer on Stackoverflow