Ios UINavigationController:在每次转换后显示具有不同方向的嵌入式视图控制器?

Ios UINavigationController:在每次转换后显示具有不同方向的嵌入式视图控制器?,ios,swift,uiviewcontroller,uinavigationcontroller,uikit,Ios,Swift,Uiviewcontroller,Uinavigationcontroller,Uikit,这是有关StackOverflow的常见问题,但其他解决方案都不起作用。许多也是几年前写的 以下是考虑的一些职位: 我们在UINavigationController中嵌入了几个视图控制器:a、B、C、D A、 B使用肖像 C、 D使用景观 A是根控制器 假设B被推到A上,因为B是纵向的。但是,当C被推到B上时,屏幕不会旋转,因为类文档状态为: 通常,系统仅在根视图上调用此方法 显示用于填充窗口的窗口控制器或视图控制器 整个屏幕;子视图控制器使用窗口的部分 由其父视图控制器提供,不

这是有关StackOverflow的常见问题,但其他解决方案都不起作用。许多也是几年前写的

以下是考虑的一些职位:

我们在UINavigationController中嵌入了几个视图控制器:a、B、C、D

A、 B使用肖像

C、 D使用景观

A是根控制器

假设B被推到A上,因为B是纵向的。但是,当C被推到B上时,屏幕不会旋转,因为类文档状态为:

通常,系统仅在根视图上调用此方法 显示用于填充窗口的窗口控制器或视图控制器 整个屏幕;子视图控制器使用窗口的部分 由其父视图控制器提供,不再 直接参与关于支持哪些旋转的决策

因此,在自定义UINavigationController中重写
supportedInterfaceOrientations
没有帮助,因为在嵌入式控制器中的转换过程中没有参考它

实际上,我们需要一种在转换时强制改变方向的方法,但似乎没有支持这种方法

下面是我们重写UINavigationController的方式(扩展现在仅用于调试目的,因为显然扩展不应用于重写):

在嵌入式视图控制器中,我们尝试如下设置方向:

override var shouldAutorotate: Bool {
    return true
}


override var preferredInterfaceOrientationForPresentation : UIInterfaceOrientation {
    return UIInterfaceOrientation.landscapeRight
}


override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.landscapeRight
}
总而言之,目标是:

1) 以不同方向显示嵌入UINavigationController中的视图控制器

2) VC转换应产生适当的方向变化(例如,从C->B弹出应产生纵向,从D->C弹出应产生横向,从B->C推应产生横向,从A->B推应产生纵向)

如果可以强制UINavigationController进入一个方向(使用公共支持的方法),一个可能的解决方案是在显示新的视图控制器时强制方向。但这似乎也不可能

建议?

步骤1 子类
UINavigationController

class LandscapeNavigationController: UINavigationController {
    public var vertical: Bool = true

    override var shouldAutorotate: Bool {
        get { return true }}

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        get { return (vertical) ? .portrait : .landscapeLeft }}

    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        get { return (vertical) ? .portrait : .landscapeLeft }}
}
@IBAction func doBack(_ sender: UIBarButtonItem) {
    if let navigationController = navigationController {
        navigationController.dismiss(animated: true, completion: {
        })
    }
}
步骤2 对于不同的方向,使用不同的
UINavigationController
。是的,在以前的
UINavigationController
上推一个新的
UINavigationController
基本上是模态的,但是转换看起来不错

为了更加方便,请使用用户定义的运行时属性来控制
LandscapeNavigationController
的方向

class LandscapeNavigationController: UINavigationController {
    public var vertical: Bool = true

    override var shouldAutorotate: Bool {
        get { return true }}

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        get { return (vertical) ? .portrait : .landscapeLeft }}

    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        get { return (vertical) ? .portrait : .landscapeLeft }}
}
@IBAction func doBack(_ sender: UIBarButtonItem) {
    if let navigationController = navigationController {
        navigationController.dismiss(animated: true, completion: {
        })
    }
}

步骤3 添加一个pop方法来处理now modal
UIViewController
上的后退按钮

class LandscapeNavigationController: UINavigationController {
    public var vertical: Bool = true

    override var shouldAutorotate: Bool {
        get { return true }}

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        get { return (vertical) ? .portrait : .landscapeLeft }}

    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        get { return (vertical) ? .portrait : .landscapeLeft }}
}
@IBAction func doBack(_ sender: UIBarButtonItem) {
    if let navigationController = navigationController {
        navigationController.dismiss(animated: true, completion: {
        })
    }
}

行动中 请注意视图C上的顶部标签和底部标签是如何正确布局的




► 在上找到此解决方案,并在上找到其他详细信息。

我们在发布悬赏后立即完成此操作,但会给您答案,但即使在演示时也存在一个问题,即如果您将第二个UINavigationController保留在肖像中,它会出现故障。下面是要呈现的代码:`let nc=storyboard!。实例化eviewController(标识符为:“NavigationControllerID2”)为!UINavigationController让vc=nc.topViewController为!TestViewController vc.data=数据存在(nc,动画:true,完成:nil)`我明白了。我已经添加了一个链接到Swift 3项目供您试验。请注意,允许用户更改方向并先发制人地强加方向可能会导致不可预知的后果。抱歉,自动更正。这意味着“演示”存在问题,而不是“甚至演示”。您是否存在此故障(第一次工作正常,但随后出现故障)?这些故障似乎与此错误有关:
\u BSMachError:端口7837;(os/kern)无效功能(0x14)“无法插入拷贝发送”
谷歌搜索和检查也不能产生有效的解决方案。你是说在日志中?还是视觉故障?使用我链接到的项目,以及用于导航的故事板片段,都不是这样的。