Swift iOS - 如何在特定选项卡中隐藏tabBar,但在设备旋转时隐藏其他选项卡

时间:2018-06-15 20:37:32

标签: ios swift uiviewcontroller uitabbarcontroller device-orientation

我的应用是基于标签的,仅限肖像。在特定视图控制器内部,我有一个固定在场景顶部的16x9视图,显示YouTube在.portrait方向时所做的视频。与YoutTube一样,我允许特定的vc旋转到.landscapeRight.landscapeLeft以全屏模式显示该视频。我打电话给func canRotate()来实现这一点,我在AppDelegate中实现了功能。其他选项卡或vcs都不能旋转。

当设备旋转时,在带有视频的vc内部我使用通知来确定方向,并且由于视频在.landscapeRight.landscapeLeft全屏显示,我隐藏了标签栏。

我遇到的问题是,当我在tab2或tab3等不同的标签上时,当我旋转设备时,tabBar会因为VideoVC内部发生的事情而被隐藏。其他标签/ vcs不会旋转,但在.landscapeRight.landscapeLeft方向

时,标签栏会消失

当设备旋转但未隐藏在其他标签内时,如何将tabBar隐藏在VideoVC中?

在tab0里面,这是VideoVC:

NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: .UIDeviceOrientationDidChange, object: nil)

@objc func deviceOrientationDidChange(){

        switch UIDevice.current.orientation {

        case .landscapeRight:

            view.transform = transform.rotated(by: -CGFloat.pi / 2)
            tabBarController?.tabBar.isHidden = true

        case .landscapeLeft:

            view.transform = transform.rotated(by: CGFloat.pi / 2)
            tabBarController?.tabBar.isHidden = true

        case .portrait:

            view.transform = CGAffineTransform.identity
            tabBarController?.tabBar.isHidden = false

        default: break
        }
}

@objc func canRotate(){} // allows this vc to rotate

的AppDelegate:

...if (rootViewController.responds(to: Selector(("canRotate")))) {
          // Unlock landscape view orientations for this view controller
          return .allButUpsideDown;
   }

我尝试使用通知禁用将tabBar隐藏在其他标签中,这些标签中的vcs无法旋转,但它很棘手。它阻止了tabBar在旋转时隐藏在VideoVC中,或者如果我在按下Notifications选项卡之前在VideoVC中旋转了视频,那么它仍然会隐藏tabBar。

NotificationVC:

@objc func deviceOrientationDidChange(){

        switch UIDevice.current.orientation {

        case .landscapeRight, .landscapeLeft, .portrait:
            tabBarController?.tabBar.isHidden = false    

        defaults: break
        }
}

tab0 with VideoVC .portrait(可以旋转):

tab0 with VideoVC .portrait

tab0 with VideoVC .landscapeLeft(可以旋转):

tab0 with VideoVC .landscapeLeft

tab3 with NotificationsVC .portrait(无法旋转):

tab3 with NotificationsVC .portrait

tab3 with NotificationsVC .landscapeLeft(不能旋转,但tabBar是隐藏的,不应该 - 这是问题):

tab3 with NotificationsVC .landscapeLeft

1 个答案:

答案 0 :(得分:0)

修复很简单(尽管需要花费数小时才能搞清楚)。我所要做的只是检查view.window!= nil并将其中的通知选择器中的内容包装起来。

if (self.view.window != nil) {
   // put the what's inside the notification's selector in here
}

问题是因为VideoVC和NotificationsVC都被实例化了,我用来检测方向改变的通知是检查UIDevice本身,而VideoVC的视图是否可见。无论我在哪个vc,它仍会响应设备被告知在方向更改时使用tabbar做的任何事情。

NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: .UIDeviceOrientationDidChange, object: nil)

@objc func deviceOrientationDidChange(){

        // no matter what vc I was in this was still running
        switch UIDevice.current.orientation {

        case .landscapeRight:

            view.transform = transform.rotated(by: -CGFloat.pi / 2)
            tabBarController?.tabBar.isHidden = true

        case .landscapeLeft:

            view.transform = transform.rotated(by: CGFloat.pi / 2)
            tabBarController?.tabBar.isHidden = true

        case .portrait:

            view.transform = CGAffineTransform.identity
            tabBarController?.tabBar.isHidden = false

        default: break
        }
}

修复是将UIDevice.current.orientation switch语句包装在if (self.view.window != nil) {}中,NotifcationsVC不再响应设备方向,因为VideoVC窗口不再可见。

<强>代码:

@objc func deviceOrientationDidChange(){

    // use this to check if this view's window isn't nil
    if (self.view.window != nil) {

        switch UIDevice.current.orientation {

           case .landscapeRight:

            view.transform = transform.rotated(by: -CGFloat.pi / 2)
            tabBarController?.tabBar.isHidden = true

        case .landscapeLeft:

            view.transform = transform.rotated(by: CGFloat.pi / 2)
            tabBarController?.tabBar.isHidden = true

        case .portrait:

            view.transform = CGAffineTransform.identity
            tabBarController?.tabBar.isHidden = false

        default: break
        }
    }
}