原文连接: Preventing Popovers on Popovers
原文做者: Douglas Hill
译文出自: 掘金翻译计划
译者: llp0574
校对者: yifili09,Graning
译者注:转载请保留此头部。ios
iOS 9 的页面用了一种咱们不能复现的方式去展现一个活动视图控制器,而且当从内部表单和弹窗呈现操做列表和活动视图控制器时 UIKit 的行为一开始看起来不那么连贯。咱们提交了两份 Radars 给苹果:rdar://27448912 Can’t show activity view controller filling a form sheet 和 rdar://27448488 Reading an alert controller’s popoverPresentationController property changes behavior。git
iOS 的人机交互指南声明:github
不要在一个弹窗上展现一个模态视图。 因为一个警告弹窗多是一个异常,因此不该该在这上面展示任何东西。极少数状况下,当你真的须要在一个动做致使弹窗后展现一个模态视图时,应该先把弹窗关闭掉再进行展现。app
而且:iview
一次只展现一个弹窗。 展现多个弹窗会让交互变得杂乱并让人产生疑惑。千万不要展现一个级联或者有层次结构的弹窗,一个从另外一个里面产生的那种。若是你须要展现一个新的弹窗,首先关闭已经弹出的那个。ide
在横向水平的普通环境和全屏紧凑的环境下具备弹窗样式的视图控制器都应该呈现为弹窗。具备操做列表样式的 UIActivityViewController
和 UIAlertController
都遵照相同的规则:展现为弹窗或者一个上拉式表。因此若是一个弹窗展现一个活动视图控制器或者一个操做列表到底会发生什么?这我的机交互指南文档的说法好像有点矛盾。ui
在 iOS 9 页面的一个相关说明里,咱们注意到在一个表单的视图控制器展现了一个填充了这个表单的 UIActivityViewController
,想知道这是否是一个咱们以前没有留意到的默认行为呢?又或者它是否是一个咱们能够自定义实现的东西?spa
对于大多数视图控制器来讲,在里面展现一个弹窗或者表单须要将当前视图控制器的 modalPresentationStyle
设置为 currentContext
或者 overCurrentContext
。但对于某些像 UIActivityViewController
和 UIAlertController
这种 UIKit 提供的视图控制器来讲,它们已经被赋予了本身的样式,modalPresentationStyle
的变化将被忽略掉。翻译
通常,UIActivityViewController
会在常规宽度下展现为弹窗,在紧凑宽度下变成一个透明的表。可是若是一个常规宽度的视图控制器要从一个紧凑宽度的视图控制器里展现会怎么样呢?这种状况会在一个有表格或者弹窗 的 modalPresentationStyle
的视图控制器要在 iPad 上展现,或者它是一个使用了 overrideTraitCollection
属性的自定义展现控制器,而后这个控制器展现了一个 UIActivityViewController
。code
首先咱们来看看 UIAlertController
。图中根视图控制器(青色)用弹窗样式(下方,经过切分视图行为以做参考)展现了第二个用表单样式(上方)的视图控制器(粉色)。而后第二个视图控制器展现了一个操做列表样式的警告控制器。
虽然咱们想要用列表的展现样式去展现操做列表(而不是弹窗),但由于关注点分离的优点,我设置了警告控制器的 popoverPresentationController.sourceView
和 popoverPresentationController.sourceRect
,视图控制器不该该对它怎么展现做出假设。它应该在 app 的其余部分进行全屏展现,视图控制器不该该控制这些行为。
出于好奇,我尝试注释掉了popoverPresentationController
的定义,发生了让我意想不到的状况:
原来只读取警告控制器的popoverPresentationController
属性会致使即便是从一个紧凑宽度环境下呈现它也会展现为一个弹窗。若是你想这么作,请必定要确保好视图控制器展示的先后环境,由于若是你想从常规宽度的环境展示一个没有设置弹窗源码的警告控制器,UIKit 就会抛出一个异常。切记在展示触发的时候即便呈现视图控制器是在一个紧凑宽度环境下,当展现被激活的时候它仍是有可能发生改变。
用UIActivityViewController
作一样的事情,并指定弹窗源码信息,出现下面的状况:
不一样于页面的行为,我发现表单把这个活动视图控制器展现为一个弹窗,弹窗将活动视图控制器展现在表单上。这是在 iOS 10 的新行为,iOS 9 里,是从另外一个弹窗展现一个弹窗。
用一样不访问popoverPresentationController
的技巧致使 UIKit 抛出一个异常说“必须为这个弹窗提供位置信息”。
咱们发现当 UIKit 的视图控制器是从一个展现在常规宽度环境的紧凑宽度的环境中展现时行为会变得很混乱。弹窗展示的通常规则是在常规宽度下展现为弹窗,在紧凑宽度下为全屏(尽管结合当前上下环境更有意义)。操做列表和活动视图控制器的展现有点像弹窗的展现,但不要彻底按照通常的规则来展现。
实际的行为看起来像是和人机交互指南说的同样,并很大程度上忽略了特征集合的 Size 类。UIKit 不会在操做列表的异常警告上展示一个弹窗。Size 类并不能控制全部的东西。
咱们不能重现页面(Pages)的行为。对于咱们来讲,当一个表单展现一个活动视图控制器时,它将展现为弹窗。我把这个问题报告给了 Apple :rdar://27448912 Can’t show activity view controller filling a form sheet。若是你知道解决这个问题的方法,麻烦在个人 Twitter 留言。