如何使Xcode 6自适应UI与iOS 7和iOS 6向后兼容?

137

我刚刚观看了WWDC视频#216,“使用UIKit构建自适应UI”。

大约在45:10的时候,Tony Ricciardi谈到了Xcode 6中IB的变化以支持新变化。

他说“您可以将这些文档向后部署到旧版本的iOS”。

(其中“这些文档”可能是具有不同大小类别的特定设置的XIB和storyboard。)

我没有编造这个。去看看WWDC视频。

那怎么可能呢?Trait collections和size classes只在iOS 8中定义。基于新的iOS 8 UI构造的运行时行为如何在之前的iOS版本中工作?

如果可以实现,那将是太好了。您可以构建可在iOS 6、7和8上运行的应用程序,并利用苹果在Xcode 6中添加的新的灵活UI布局能力。我已经在代码中创建了自适应UI逻辑,这需要相当多的工作。


2
现在苹果还有一份文档描述了与版本小于8的兼容性,链接如下:https://developer.apple.com/library/ios/recipes/xcode_help-IB_adaptive_sizes/chapters/DeployingSizeClassesonEarlieriOSVersions.html#//apple_ref/doc/uid/TP40014436-CH13-SW1 - Alladinian
8个回答

151

在Interface Builder中使用Size Classes进行UI更改,确实会在iOS 7设备和Xcode预览中正确显示。例如,我更改了一些针对普通高度和普通宽度的自动布局约束和字体大小,这些更改的约束在运行iOS 7.0的iPad模拟器中可见。

除了具有紧凑高度的Size Classes之外,所有Size Class优化都可用于iOS 7,苹果已证实并直接在文档中说明:

对于支持比iOS 8早期版本的应用程序,大多数Size Classes都是向后兼容的。

当以下条件得到满足时,Size Classes是向后兼容的:
- 应用程序使用Xcode 6或更高版本构建
- 应用程序的部署目标早于iOS 8
- Size Classes在Storyboard或xib中指定
- 高度组件的值不是紧凑的

因为iOS 7不支持某些Size Classes,如果您使用它们,就会遇到问题。例如: 当定义了Compact w Any h,然后定义了Compact w Compact h时,在iOS 7上它会遵循Compact w Any h,但在iOS 8上会呈现Compact w Compact h的外观。

因此,如果您想利用这两个Size Classes并保持与iOS 7的兼容性,我建议您在Any w Any h或Compact w Any h中进行任何针对iPhone横屏的优化,然后根据需要执行其他Size Classes的优化处理,这样您就不需要使用任何具有紧凑高度的Size Class,并避免遇到问题。


在设备上测试正则/常规,它不响应大小类自定义,我只得到Beta 7的任何/任何。 - hokiewalrus
@hokiewalrus 我刚刚使用 Xcode 6 beta 7 进行了检查,并获得了我在答案中详细说明的完全相同的结果。在 IB 中更改 Regular Regular 的框的宽度确实可以在运行 iOS 7.1 的 iPad 上正确显示。 - Jordan H
@Joey 嗯,对于我来说,模拟器或物理设备都不响应大小类7.1。希望这只是我的beta 7安装中的一个错误,并且它将在GM版本中得到修复。 - hokiewalrus
3
@Joey,这不是一个 bug,而是有意为之。Compact-Compact 对于 iOS 7 并没有被导出;相反,Compact-Regular 被导出了。请查看我的答案以获取更多细节。 - Dave DeLong
2
应该接受这个答案,上面的回答是误导性的。 - Dominic Lacaille
显示剩余7条评论

68

在将您的应用程序部署到iOS 7时,Xcode会以两种不同的方式编译您的故事板:

  • 对于iPhone,您的故事板将被编译为“紧凑-常规”(紧凑宽度,常规高度),并作为“~iphone” nib打包。

  • 对于iPad,您的故事板将被编译为“常规-常规”,并作为“~ipad” nib打包。

因此,如果您想要部署到iOS 7和iOS 8,则应专注于紧凑-任意和常规-任意大小类的设计。这将为您提供最佳体验,以匹配跨部署目标的UI。当然,您可以修改其他大小类的布局,但除非这些修改应用于紧凑-常规或常规-常规大小类,否则您将在iOS 7上看不到这些修改。


我理解你的回答是,“Regular-Regular”应该在iPad iOS7上可以工作。但它并没有工作。我已经在XCode6 GM版本中进行了测试。如果我误解了你的回答,请纠正我。 - Iducool
4
似乎“常规 - 常规”只适用于Storyboard,而不适用于XIB。 - Boris Charpentier
@BorisCharpentier 我已经关于此事报告了一个错误 rdar://18737656,该错误被关闭并作为已开放的#18490866的重复项。 - Maxim Pavlov
@BorisCharpentier,你找到XIB的解决方案了吗? - saadnib
@saadnib 我要转换到完整的故事板。 - Boris Charpentier
4
@BorisCharpentier,我刚发现这个问题已经在XCode 6.1.1中解决了 :-) - saadnib

27

注意:这个答案适用于Xcode 6的beta版本,对于最终版本已经不再适用。请参考本页面JoeyDave DeLong的答案获取正确信息。

(下面是原始答案):


虽然配置为使用大小类的Storyboards / XIBs可以在iOS 7上运行,但该操作系统目前不支持这些 size classes ,似乎使用默认的“任何/任何”大小类。
我同意你提到的特定幻灯片似乎承诺了这种兼容性,但当前情况似乎并非如此(Xcode 6 beta 2)
为了测试,我创建了一个项目(iOS 8 SDK,部署目标为7.1),其中有一个单独的按钮,该按钮位于任何/任何大小类中心垂直和水平,但在压缩/压缩大小类中左上对齐(例如,iPhone处于横向)。 Xcode的预览助手显示,该按钮在iOS 8中更改其位置,但不是iOS 7。我也在iOS 7设备上确认了这种行为。

Roy,谢谢回复。我还没有时间亲自测试这个,我很感激。那个视频中的演讲者应该更清楚一些。我认为他必须是指XIB / Storyboard文件可以被iOS 6和7读取,但不支持自适应UI。它使得编写在iOS <8上运行的应用程序变得棘手。 - Duncan C
确实。我想知道是否有关于如何在同一个Storyboard/XIB中支持新的尺寸类和旧的方向/习惯用法方法的官方文档。如果我找到了任何信息,我会更新答案。 - remmah
根据我的经验,苹果似乎认为一旦发布新版本,旧的操作系统版本就不存在了。实际上,工程团队似乎在新版本发布后就停止关注当前版本,并开始将所有精力集中在下一个主要版本上。我从未在当前主要版本中修复过我提交的错误。 - Duncan C
3
Xcode 6 beta 4似乎不再是这种情况了。请参见我刚添加的回答。 - Jordan H
这真的不应该成为被接受的答案,因为它提供了错误的信息。在Storyboard中进行的所有尺寸类别优化都会在iOS 7上得到尊重,除了紧凑高度尺寸类别的优化。 - Jordan H
1
@Joey 谢谢你提醒我,我已经编辑了我的答案,将读者引用到你和 Dave 的答案。 - remmah

12

由于一些答案和评论正在讨论向后兼容性的本质,因此我想分享一段节选自苹果文档的内容:

~~~~~

在早期版本的 iOS 上部署具有大小类的应用程序

对于支持早于 iOS 8 的 iOS 版本的应用程序,大多数大小类都是向后兼容的。

当以下条件满足时,大小类就是向后兼容的:

  • 应用程序使用 Xcode 版本 6 或更高版本构建
  • 应用程序的部署目标早于 iOS 8
  • 在 storyboard 或 xib 中指定了大小类
  • 高度组件的值不是紧凑型

~~~~~

这最后一个要点是针对本次讨论的,苹果确认只要不使用“紧凑高度”,它就应保持向后兼容性。

希望这能帮助到某个人!


太好了,现在有文档记录了,感谢您的发布! - Jordan H

3
在处理类似问题时,我发现了另一个答案,但我在这里还没有看到。看起来,在 XIB 文件中的大小类别根本不起作用。如果我在 storyboard 文件中创建单元格原型,则在 iOS7 中按其他答案中所述工作,但是当将相同的原型单元格移动到单独的 XIB 文件中时,在 iOS7 中会忽略大小类别。
这是演示此行为的示例项目链接:https://dl.dropboxusercontent.com/u/6402890/testSizeClasses.zip 在原型单元格中,我有来自灰色视图每个边缘的四个约束。每个都以相同的方式配置:任何/任何-10、常规/常规-20。

enter image description here

在iOS8模拟器中,XIB和Storyboard都可以正常工作,在iPad上只有在Storyboard中定义的单元格会更新约束条件,而在iOS7中则正常。

enter image description here


这里我有很多XIB文件需要在iOS 7和8上部署,$^%$ ^%@#^&@#%&^%... - TheEye
没错。我正在将 iPhone 和 iPad 的故事板结合在一起,我觉得将单元格分离到它们自己的 XIB 文件中会有所帮助 :)。如果你能支持我的答案,我将不胜感激。 - sha
1
我也遇到了同样的问题。 - bjtitus

2
如果有人想要节省时间,我认为Xcode 6实现准向后兼容的尺寸类方式是通过历史的带有“~ipad”和“~iphone”后缀的故事板,没有其他办法。这很合理,因为尺寸类是我们以前定义iPad故事板和iPhone故事板的更抽象的方式。
因此:
• 如果你的目标是使用尺寸类来支持特定设备系列的布局(iPad与iPhone),那么你很幸运:尺寸类是先前支持的方法的更好的接口。
• 如果你的目标是使用尺寸类来支持同一设备系列中不同型号的更改布局-例如iPhone 5/6/6+包括横向布局,那么你就没那么幸运了。使用这些将需要至少iOS 8的部署目标。

1
很遗憾,Dave和Joey的回答对我没有用。 我不允许在这个帖子中发表评论,如果这是错误的地方,请原谅我。
我为此提出了一个具体的问题: iPhone纵向横向自适应UI的示例,向后兼容iOS 7 从我目前所学的知识来看,我认为像我的例子一样,在iPhone iOS7上使用大小类别无法为一个UI元素在纵向和横向模式下设置2个不同的约束条件。 不过如果我错了,我会很高兴的。

1

@lducool - 在界面构建器中的身份检查器中,将“构建目标”更改为iOS7.1及更高版本。


没有输出上的差异。 - Iducool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接