导航弹出动画意外 - 跳出屏幕
Navigation pop animation unexpected - jumps off screen
我遇到一个问题,我的 UINavigationController
的默认弹出动画有意外行为 - 弹出的控制器有时会向左或向右 off-screen 跳动。
这个问题似乎与覆盖控制器的 UITraitCollection
。
我有一个通用应用程序,在 iPad 上,一个自定义 UIPresentationController
以部分模式显示导航,其宽度是屏幕宽度的一小部分。因此,我覆盖 horizontalSizeClass
以压缩 UIPresentationController
的 overrideTraitCollection
属性,因此此 "half modal" 中出现的所有控制器都假定其 iPhone布局。
覆盖该大小 class 似乎会触发错误。突然,当在那个 "half modal" 中弹出一个控制器时,动画横向混乱(它要么向左跳,要么向右跳)。
下面是它的外观示例:
尝试次数
首先,当我摆脱 traitCollection
覆盖时,错误消失了。显然,我想覆盖水平尺寸 class,因为这些视图也在常规环境中的其他地方重复使用。
因此,我尝试以其他方式覆盖模态 children 的 horizontalSizeClass
,例如:
- 使用模态导航的
UINavigationControllerDelegate
覆盖
每个 child 的 traitCollection
navigationController:didShowViewController:animated:
– 这似乎没什么区别
- 第一个导航 child 覆盖第二个 child 的
traitCollection
在它推动它之前
像这样:
[self.navigationController setOverrideTraitCollection:compactTraitCollection forChildViewController:secondaryController];
[self.navigationController pushViewController:secondaryController animated:YES];
有趣的是,这修复了弹出动画错误,但我的主控制器 (self
) 仍处于常规状态 horizontalSizeClass
...此外,这似乎是一种不好的做法。我的视图控制器不需要知道任何关于它们的展示!这应该由 UIPresentationController
处理,并且显示控制器具有 overrideTraitCollection
属性.
的事实似乎支持了这一点
原来罪魁祸首是 supportedInterfaceOrientations
的实现,依赖于大小 类:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
// Don't do this if you ever override size classes
if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular)
{
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
因为“半模态”控制器的 horizontalSizeClass
被覆盖为使用 UIUserInterfaceSizeClassCompact
,它们假定为仅纵向。导航控制器不知道如何处理。
解决方法:
更改以上代码以依赖于设备类型修复了问题:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
// Basing off of size classes causes unexpected behavior when overriding size classes - use interface idiom instead
if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
这可能本来应该是首先要走的路,但考虑到 Apple 鼓励与设备无关并且只依赖大小 类,这不是我所做的。
无论如何,为了繁荣,这是我用来调试这个的测试项目:https://github.com/bradgmueller/half-modal-test
我遇到一个问题,我的 UINavigationController
的默认弹出动画有意外行为 - 弹出的控制器有时会向左或向右 off-screen 跳动。
这个问题似乎与覆盖控制器的 UITraitCollection
。
我有一个通用应用程序,在 iPad 上,一个自定义 UIPresentationController
以部分模式显示导航,其宽度是屏幕宽度的一小部分。因此,我覆盖 horizontalSizeClass
以压缩 UIPresentationController
的 overrideTraitCollection
属性,因此此 "half modal" 中出现的所有控制器都假定其 iPhone布局。
覆盖该大小 class 似乎会触发错误。突然,当在那个 "half modal" 中弹出一个控制器时,动画横向混乱(它要么向左跳,要么向右跳)。
下面是它的外观示例:
尝试次数
首先,当我摆脱 traitCollection
覆盖时,错误消失了。显然,我想覆盖水平尺寸 class,因为这些视图也在常规环境中的其他地方重复使用。
因此,我尝试以其他方式覆盖模态 children 的 horizontalSizeClass
,例如:
- 使用模态导航的
UINavigationControllerDelegate
覆盖 每个 child 的traitCollection
navigationController:didShowViewController:animated:
– 这似乎没什么区别 - 第一个导航 child 覆盖第二个 child 的
traitCollection
在它推动它之前
像这样:
[self.navigationController setOverrideTraitCollection:compactTraitCollection forChildViewController:secondaryController];
[self.navigationController pushViewController:secondaryController animated:YES];
有趣的是,这修复了弹出动画错误,但我的主控制器 (self
) 仍处于常规状态 horizontalSizeClass
...此外,这似乎是一种不好的做法。我的视图控制器不需要知道任何关于它们的展示!这应该由 UIPresentationController
处理,并且显示控制器具有 overrideTraitCollection
属性.
原来罪魁祸首是 supportedInterfaceOrientations
的实现,依赖于大小 类:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
// Don't do this if you ever override size classes
if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular)
{
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
因为“半模态”控制器的 horizontalSizeClass
被覆盖为使用 UIUserInterfaceSizeClassCompact
,它们假定为仅纵向。导航控制器不知道如何处理。
解决方法:
更改以上代码以依赖于设备类型修复了问题:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
// Basing off of size classes causes unexpected behavior when overriding size classes - use interface idiom instead
if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
这可能本来应该是首先要走的路,但考虑到 Apple 鼓励与设备无关并且只依赖大小 类,这不是我所做的。
无论如何,为了繁荣,这是我用来调试这个的测试项目:https://github.com/bradgmueller/half-modal-test