翻译:iOS视图控制器编程指南(十三)——创建自适应界面(Building an Adaptive Interface)

一个自适应界面应该响应trait和size变化。在视图控制器基本,使用trait大体上决定你所展示的内容和内容的布局。例如,当size类改变,你会选择改变视图属性,显示或隐藏视图,或者显示一组完全不同的视图。在做出这些重大决策,使用size变化来调整你的内容。

自适应trait变化

trait提供一种方式,可以针对不同的环境以不同的方式配置app,可以使用它们来粗略的调整界面。大部分情况下,可以直接在storyboard文件中修改trait,但是有些需要额外的代码。

配置storyboard处理不同size类

界面构建器使界面自适应不同size类变得更容易。storyboard编辑器支持配置不同的size类显示界面,删除视图的具体配置,指定不同布局约束。还可以创建图像asset为不同size类提供不同图像。使用这些工具意味着不需要在运行时以编程的方式改变。相反,当当前size类改变,UIKit自动更新界面。

图13-1展示了在界面构建器中用于配置界面的工具。size类查看控制改变界面视图的外观。使用该控制可以查看给定一个size类的界面外观。对于个人视图,使用安装控制来配置该视图是否存在给定size类配置。使用复选框左边的加号(+)按钮添加新的配置。

图13-1 针对不同size类自定义界面

注意:未卸载的视图仍然在视图层级结构中,可以正常操作,但他们不会出现在屏幕上。

图片asset是存储应用图片资源的首选方法。每个图片asset包含相同图片的多个版本,每个版本用于特定配置。除了为标准和Retina显示指定不同的图片,还可以为不同水平和垂直size类指定不同图片。当配置了图片asset,UIImageView对象自动根据当前size类和分辨率选择图片。

图13-2 展示了图片asset属性。改变宽度和高度属性会在图片目录中添加slot,为每个size类对应的slot添加图片。

图13-2 为不同size类配置图片 asset

改变子视图控制器的trait

子视图控制器默认继承他们父视图控制器的trait。如size类,使每个子视图控制器与父视图控制器有相同的trait没有意义。例如,在普通环境中的视图控制器可能希望给一个或多个子视图分配一个紧凑的size类,减少子视图的空间。当实现一个容器视图控制器,通过调用容器视图控制器的setOverrideTraitCollection:forChildViewController:方法修改子视图的trait。

列表13-1展示了如何创建一组新的trait,并将其关联到子视图控制器。只需在父视图控制器中执行一次该代码。覆盖子视图的trait直到再次改变trait或者从视图控制器层级结构中删除trait。

列表13-1 改变子视图控制器的trait
<pre><code>
UITraitCollection* horizTrait = [UITraitCollection

traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];

UITraitCollection* vertTrait = [UITraitCollection

traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];

UITraitCollection* childTraits = [UITraitCollection

traitCollectionWithTraitsFromCollections:@[horizTrait, vertTrait]];

[self setOverrideTraitCollection:childTraits
forChildViewController:self.childViewControllers[0]];

</pre></code>

当改变父视图控制器的trait,子视图继承任何没有显式覆盖父类的trait。例如,当父视图控制器的水平size类从常规变成紧凑,在前面例子中的视图控制器保持其常规水平size类。然而,如果displayScale trait改变,子视图继承新值。

presented视图控制器自适应新样式

presented视图控制器在水平常规和紧凑环境中自适应。当从水平常规环境过渡到水平紧凑环境时,UIKit默认改变内置present风格为 UIModalPresentationFullScreen。对于自定义present风格,present控制器可以决定适应行为并根据情况调整。

对于一些app,采用全屏风格可能存在问题。例如,通常点击其他区域,弹窗dismiss,但在紧凑环境中不可能这样做,弹窗覆盖整个屏幕,如图13-3所示。当默认自适应风格不合适,可以告诉UIKit使用不同的风格或者present一个完全不同视图控制器,使之更适合全屏风格。

图13-3 在常规和紧凑环境中的弹窗

要改变present风格的默认自适应行为,分配 delegate 到相关present控制器。使用presented视图控制器的 presentationController 属性访问presentation控制器。presentation控制器在做出自适应相关更改前查询代理对象。代理可以返回不同Presentation风格,而不是默认的。代理可以提供Presentation控制器另一个要显示的视图控制器。

使用代理的adaptivePresentationStyleForPresentationController: 方法指定不同presentation风格而不是默认风格。当过渡到紧凑环境时,仅支持的样式是两种全屏风格或UIModalPresentationNone。返回UIModalPresentationNone告诉Presentation控制器忽视紧凑环境并继续使用前面的Presentation风格。如果是弹窗,忽视变更,提供类似iPad上的弹窗。在图13-4中展示了默认全屏自适应和不适应,这样你可以比较present结果。

图13-4 改变presented视图控制器的自适应行为

要完全取代视图控制器,实现代理的presentationController:viewControllerForAdaptivePresentationStyle: 方法。当自适应紧凑环境时,使用该方法插入导航控制器到视图层级结构或者加载为小空间设计的视图控制器。

实现自适应popover的提示

当从水平常规变为水平紧凑环境时,弹窗需要额外的修改。水平紧凑默认将弹窗改为全屏present。通常通过点击弹窗外区域dismiss弹窗,当变为全屏present时无法dismiss弹窗。可以通过以下方式实现:

响应size变化

size发生变化的原因有很多,包括以下几点:

  • 底层窗口的尺寸改变,通常因为方向改变。
  • 父视图控制器调整子视图控制器的size。
  • present控制器改变presented视图控制器的size。

当size发生变化时,UIKit通过正常布局过程,自动更新可见视图控制器的size和position。如果使用Auto Layout约束指定视图的size和position,app自适应任何size变化并运行在不同屏幕尺寸的设备上。

如果Auto Layout约束不能满足你的要求,可以使用viewWillTransitionToSize:withTransitionCoordinator:方法改变布局。还可以使用该方法创建额外动画。例如,在界面旋转过程中,使用过度协调器的targetTransform 属性来创建界面的逆转矩阵。

官方原文地址:

https://developer.apple.com/library/prerelease/ios/featuredarticles/ViewControllerPGforiPhoneOS/BuildinganAdaptiveInterface.html#//apple_ref/doc/uid/TP40007457-CH32-SW1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容