Swift iOS - 如何在设备旋转时隐藏特定选项卡中的 tabBar 而不是其他选项卡
Swift iOS -How to hide tabBar in specific tab but not other tabs when device rotates
我的应用程序是基于选项卡的,并且只有纵向。在一个特定的视图控制器中,我有一个固定在场景顶部的 16x9 视图,它显示视频,就像 YouTube 在 .portrait
方向时所做的那样。也像 YoutTube 一样,我允许特定的 vc 旋转到 .landscapeRight
或 .landscapeLeft
以全屏模式显示该视频。我调用 func canRotate()
来实现这一点,并且我在 AppDelegate 中实现了它的功能。其他选项卡的 None 或 vc 可以旋转。
在设备旋转时的 vc 视频中,我使用通知来确定方向,并且由于视频在 .landscapeRight
或 .landscapeLeft
中全屏显示,我隐藏了标签栏。
我遇到的问题是,当我在不同的选项卡(例如 tab2 或 tab3)上时,当我旋转设备时,由于 VideoVC 内部发生的事情,tabBar 被隐藏了。另一个 tabs/vcs 不旋转,但 tabBar 在 .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;
}
我尝试使用 Notification 来禁止在其他选项卡中隐藏 tabBar,这些选项卡有 vcs 不能旋转,但它很奇怪。它防止 tabBar 在旋转时隐藏在 VideoVC 中,或者如果我在按下通知选项卡之前在 VideoVC 中旋转了视频,那么它仍然会在那里隐藏 tabBar。
通知VC:
@objc func deviceOrientationDidChange(){
switch UIDevice.current.orientation {
case .landscapeRight, .landscapeLeft, .portrait:
tabBarController?.tabBar.isHidden = false
defaults: break
}
}
带有 VideoVC .portrait(可以旋转)的 tab0:
tab0 with VideoVC .landscapeLeft(可以旋转):
带有 NotificationsVC .portrait 的 tab3(无法旋转):
带有 NotificationsVC .landscapeLeft 的 tab3(无法旋转,但 tabBar 被隐藏且不应该 - 这就是问题所在):
修复很简单(虽然花了几个小时才弄明白)。我所要做的就是检查 view.window != nil 并将通知选择器中的内容包装在其中。
if (self.view.window != nil) {
// put the what's inside the notification's selector in here
}
问题是因为 VideoVC 和 NotificationsVC 都被实例化了,我用来检测方向变化的 Notification 正在检查 UIDevice 本身,无论 VideoVC 的视图是否可见。无论 vc 我在其中,它仍然会响应设备被告知在方向更改时使用标签栏执行的任何操作。
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 window 不再可见。
代码:
@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
}
}
}
我的应用程序是基于选项卡的,并且只有纵向。在一个特定的视图控制器中,我有一个固定在场景顶部的 16x9 视图,它显示视频,就像 YouTube 在 .portrait
方向时所做的那样。也像 YoutTube 一样,我允许特定的 vc 旋转到 .landscapeRight
或 .landscapeLeft
以全屏模式显示该视频。我调用 func canRotate()
来实现这一点,并且我在 AppDelegate 中实现了它的功能。其他选项卡的 None 或 vc 可以旋转。
在设备旋转时的 vc 视频中,我使用通知来确定方向,并且由于视频在 .landscapeRight
或 .landscapeLeft
中全屏显示,我隐藏了标签栏。
我遇到的问题是,当我在不同的选项卡(例如 tab2 或 tab3)上时,当我旋转设备时,由于 VideoVC 内部发生的事情,tabBar 被隐藏了。另一个 tabs/vcs 不旋转,但 tabBar 在 .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;
}
我尝试使用 Notification 来禁止在其他选项卡中隐藏 tabBar,这些选项卡有 vcs 不能旋转,但它很奇怪。它防止 tabBar 在旋转时隐藏在 VideoVC 中,或者如果我在按下通知选项卡之前在 VideoVC 中旋转了视频,那么它仍然会在那里隐藏 tabBar。
通知VC:
@objc func deviceOrientationDidChange(){
switch UIDevice.current.orientation {
case .landscapeRight, .landscapeLeft, .portrait:
tabBarController?.tabBar.isHidden = false
defaults: break
}
}
带有 VideoVC .portrait(可以旋转)的 tab0:
tab0 with VideoVC .landscapeLeft(可以旋转):
带有 NotificationsVC .portrait 的 tab3(无法旋转):
带有 NotificationsVC .landscapeLeft 的 tab3(无法旋转,但 tabBar 被隐藏且不应该 - 这就是问题所在):
修复很简单(虽然花了几个小时才弄明白)。我所要做的就是检查 view.window != nil 并将通知选择器中的内容包装在其中。
if (self.view.window != nil) {
// put the what's inside the notification's selector in here
}
问题是因为 VideoVC 和 NotificationsVC 都被实例化了,我用来检测方向变化的 Notification 正在检查 UIDevice 本身,无论 VideoVC 的视图是否可见。无论 vc 我在其中,它仍然会响应设备被告知在方向更改时使用标签栏执行的任何操作。
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 window 不再可见。
代码:
@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
}
}
}