ViewController编程指南适应性和尺寸变化-建立自定义界面

自适应界面应该响应特征和大小改变。 在视图控制器级别,您可以使用特征对显示的内容和该内容的布局进行粗略确定。 例如,当在大小类之间更改时,您可以选择更改视图属性,显示或隐藏视图,或显示完全不同的视图集。 做出这些重大决定后,您可以使用大小更改来调整您的内容。

适应特征变化

特征为您提供了一种为不同环境不同地配置应用程序的方法,您可以使用它们对界面进行粗调。 使用特征进行的大部分更改可以直接在故事板文件中完成,但有些需要额外的代码。

配置您的故事板以处理不同大小类

Interface Builder使您可以轻松地将界面适应不同大小的类。 故事板编辑器包括支持以不同大小类配置显示您的界面,用于删除特定配置中的视图以及指定不同的布局约束。 您还可以创建针对不同大小类别提供不同图像的图片资源。 使用这些工具意味着您不必在运行时以编程方式进行相同的更改。 相反,UIKit会在当前大小类更改时自动更新您的界面。

图13-1显示了在Interface Builder中用于配置界面的工具。 大小类查看控件会更改您的界面的外观。 使用该控件来查看您的界面将如何查找给定的大小类。 对于单个视图,使用安装控件配置是否存在给定大小类配置的视图。 使用复选框左侧的加号(+)按钮添加新配置。

图13-1为不同大小类自定义界面

size_class_ib_setting_2x.png

注意

已卸载的视图仍保留在视图层次结构中,可能会正常操作,但不会显示在屏幕上。

图片资源是存储应用程序图片资源的首选方式。 每个图片资源包含同一图片的多个版本,每个版本都针对特定配置进行设计。 除了为标准和Retina显示指定不同的图像,还可以为不同的水平和垂直尺寸类别指定不同的图像。 配置图像资源时,UIImageView对象会自动选择与当前大小类和分辨率相关联的图像。

图13-2显示了图像属性。 更改width和height属性会在目录中添加更多图像的插槽。 用图像填充这些插槽,以用于每个尺寸类组合。

图13-2为不同大小类别配置图像属性

size_class_image_asset_2x.png

更改子视图控制器的特征

默认情况下,子视图控制器继承其父视图控制器的特性。 对于像大小类的特征,可能没有意义每个孩子具有相同的特质作为其父。 例如,常规环境中的视图控制器可能想要向其一个或多个子项分配紧凑大小类以反映该子项的减少的空间量。 当实现容器视图控制器时,通过调用容器视图控制器的setOverrideTraitCollection:forChildViewController:方法来修改子的特征。

代码清单13-1显示了如何创建一组新特征并将它们与子视图控制器相关联。 您从父视图控制器执行此代码,只需要这样做一次。 覆盖的特征会保留在子代中,直到您再次更改它们或直到您从视图控制器层次结构中删除子代。

代码清单13-1更改子视图控制器的特征

UITraitCollection* horizTrait = [UITraitCollection
                 traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
UITraitCollection* vertTrait = [UITraitCollection
                 traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
UITraitCollection* childTraits = [UITraitCollection
                 traitCollectionWithTraitsFromCollections:@[horizTrait, vertTrait]];
 
[self setOverrideTraitCollection:childTraits forChildViewController:self.childViewControllers[0]];

当父视图控制器的特性改变时,子级继承父级没有显式覆盖的任何特性。 例如,当父级的水平大小类从正常变为紧凑时,上例中的子级保留其常规水平大小类。 但是,如果displayScale 特征更改,则子代继承新值。

使呈现的视图控制器适应新样式

呈现的视图控制器在水平规则和紧凑环境之间自动适应。 当从水平规则环境转换到水平紧凑环境时,UIKit默认将内置表示风格更改为UIModalPresentationFullScreen。 对于自定义控制器样式,呈现控制器可以确定适应行为并相应地调整呈现。

对于某些应用程序,适应全屏样式可能会出现问题。 例如,弹出窗口通常通过在其边界外部敲击来解除,但是在弹出窗口覆盖整个屏幕的紧凑环境中这样做是不可能的,如图13-3所示。 当默认的适应风格不适当时,你可以告诉UIKit使用不同的风格或呈现更完全不同的视图控制器,更好地适合全屏风格。

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

VCPG_popover-in-regular-and-compact-views_13_3_2x.png

要更改呈现样式的默认自适应行为,请将委派分配给关联的呈现控制器。 您可以使用提供的视图控制器的presentationController属性访问呈现控制器。 在进行任何适应性相关的更改之前,呈现控制器会咨询您的委托对象。 代理可以返回与默认不同的呈现样式,并且它可以向呈现控制器提供要显示的替代视图控制器。

使用委托的adaptivePresentationStyleForPresentationController:方法来指定与默认不同的表示风格。 当转换到一个紧凑的环境,唯一支持的样式是两个全屏样式或UIModalPresentationNone。 返回UIModalPresentationNone告诉呈现控制器忽略紧凑环境并继续使用先前的呈现风格。 在弹出窗口的情况下,忽略更改会给所有设备上类似iPad的popover行为。 图13-4显示了默认的全屏自适应,没有适配,因此您可以比较生成的呈现。

图13-4更改所提供的视图控制器的自适应行为

VCPG_changing-adaptive-behavior-for-presented-view-controller_13-4_2x.png

要完全替换视图控制器,请实现委托的presentationController:viewControllerForAdaptivePresentationStyle:方法。 当适应于紧凑环境时,您可以使用该方法将导航控制器插入视图层次结构或加载专为较小空间设计的视图控制器。

实现自适应弹窗的提示

当从水平正则变为水平紧凑时,弹出框需要额外的修改。 水平紧凑的默认行为会将其更改为全屏演示。 因为弹出通常通过点击弹出框的边界以外被忽略,改变为全屏显示消除了消除弹出的主要技术。 您可以通过执行以下操作之一来补偿该行为:

  • 将弹出的视图控制器推送到现有的导航堆栈。 当有父导航控制器可用时,关闭弹出并将其视图控制器推到导航堆栈上。
  • 添加控件以在全屏显示时关闭弹窗。 您可以向弹窗的视图控制器添加控件,但更好的选择是使用presentationController:viewControllerForAdaptivePresentationStyle:方法交换导航控制器的popover。 使用导航控制器为您提供了模式界面和空间,以添加完成按钮或其他控件来关闭内容。
  • 使用呈现控制器委派来消除任何适应性更改。 获取弹窗呈现控制器并分配一个委托给它实现adaptivePresentationStyleForPresentationController:方法。 从该方法返回UIModalPresentationNone会导致弹窗继续显示为弹窗。

响应大小更改

尺寸更改可能有多种原因,包括:

  • 底层窗口的尺寸改变,通常是因为方向改变。
  • 父视图控制器调整其子级之一。
  • 呈现控制器改变其呈现的视图控制器的大小。

当大小更改发生时,UIKit通过正常布局过程自动更新可见视图控制器层次结构的大小和位置。 如果您使用“自动布局”限制指定视图的大小和位置,则您的应用会自动适应任何大小更改,并应在具有不同屏幕尺寸的设备上运行。

如果您的Auto Layout约束不足以实现所需的外观,您可以使用viewWillTransitionToSize:withTransitionCoordinator:方法更改布局。 您还可以使用该方法创建附加的动画,以与大小更改动画一起运行。 例如,在界面旋转期间,您可以使用转换协调器的targetTransform属性为接口的某些部分创建反向旋转矩阵。

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

推荐阅读更多精彩内容