ios - 导航弹出动画意外 - 跳出屏幕

标签 ios uinavigationcontroller size-classes uitraitcollection

我遇到了一个问题,我的 UINavigationController的默认弹出动画有意外行为 - 弹出的 Controller 有时会向左或向右跳出屏幕。

该问题似乎与覆盖 Controller 的 UITraitCollection 有关。 .

我有一个通用应用程序,在 iPad 上,自定义 UIPresentationController以部分模式显示导航,其宽度是屏幕宽度的一小部分。因此,我覆盖了 horizontalSizeClassUIPresentationController 上进行压缩的overrideTraitCollection属性,所以在这个“半模态”中呈现的所有 Controller 都假定它们的 iPhone 布局。

覆盖该大小类似乎会触发该错误。突然,当在那个“半模态”中弹出一个 Controller 时,动画在横向上被搞砸了(它要么向左要么向右跳跃)。

这是它的外观示例:
unexpected-pop-animation

尝试

首先,当我摆脱 traitCollection覆盖,错误消失。显然,我想覆盖水平尺寸类,因为这些 View 也在常规环境中的其他地方重用。

因此,我尝试覆盖 horizontalSizeClass模态的 child 以其他方式,如:

  • 使用模态导航的 UINavigationControllerDelegate覆盖
    每个 child 的traitCollectionnavigationController:didShowViewController:animated: – 这似乎没有什么区别
  • 让第一个导航 child 覆盖次要 child 的 traitCollection在它插入它之前

  • 像这样:
    [self.navigationController setOverrideTraitCollection:compactTraitCollection forChildViewController:secondaryController];
    [self.navigationController pushViewController:secondaryController animated:YES];
    

    有趣的是,这修复了弹出动画错误,但是我的主 Controller ( self )仍然处于常规 horizontalSizeClass ...此外,这似乎是不好的做法。我的 View Controller 不需要知道任何关于他们的演示的信息!这应该由 UIPresentationController 处理。 , 并且似乎得到了演示 Controller 具有 overrideTraitCollection 的事实的支持。属性(property)。

    最佳答案

    原来罪魁祸首是 supportedInterfaceOrientations 的实现。 ,依赖于大小类:

    - (UIInterfaceOrientationMask)supportedInterfaceOrientations
    {
        // Don't do this if you ever override size classes
        if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular)
        {
            return UIInterfaceOrientationMaskAll;
        }
        return UIInterfaceOrientationMaskPortrait;
    }
    
    因为horizontalSizeClass的“半模态” Controller 被覆盖以使用 UIUserInterfaceSizeClassCompact ,他们假设只有纵向。导航 Controller 不知道如何处理。
    解决方案:
    将上述代码更改为依赖设备类型可解决问题:
    - (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

    关于ios - 导航弹出动画意外 - 跳出屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36427778/

    相关文章:

    ios - Appium 从元素获取 xpath?

    iphone - InstaPDF 和 Aviary 共存的问题

    ios - 如何将固定高度 View 添加到垂直堆栈 View ?

    ios - 为 UITabBarController subview Controller 设置相同的导航栏?

    ios - OpenGLES 上的定向绘图

    swift - 使用 Swift2 从 AppDelegate 重新打开 iOS 应用程序到指定的导航 Controller

    ios - 以编程方式实现非传统渐变图案

    ios - 如何在后端动态定义 Autolayout

    ios - 尺寸等级 : starting with Compact Regular and moving to Any Any rather than vice versa?

    swift - 在 Swift/Xcode for iOS 中,方向更改时旋转一个 View 并保持另一个 View 不变