【问题标题】:navigation bar under status bar after video playback in landscape mode横向播放视频后状态栏下的导航栏
【发布时间】:2016-03-04 19:38:35
【问题描述】:

问题:

横向播放视频后,导航栏位于状态栏下方。

应用程序:

  • 仅限 iOS9。
  • 仅支持纵向模式。
  • 视图控制器上有一个网络视图,网络视图将打开一个 youtube 链接
  • 视图控制器嵌入在导航控制器中

要重现的设置:

  1. 在 webView 中播放视频,
  2. 将设备置于横向模式。
  3. 在横向模式下关闭视频播放,应用返回纵向模式
  4. 导航栏位置错误

截图:

  1. 应用打开时

  1. 播放视频并将设备横向放置

  1. 问题:

【问题讨论】:

    标签: ios objective-c iphone swift


    【解决方案1】:

    斯威夫特 3

    在呈现视图控制器中,覆盖 prefersStatusBarHidden 属性以仅在状态栏处于横向时隐藏状态栏。

    override var prefersStatusBarHidden: Bool {
        return UIApplication.shared.statusBarOrientation.isLandscape
    }
    

    然后在设备旋转时添加一个观察者。

    override func viewDidLoad() {
        super.viewDidLoad()
    
        NotificationCenter.default.addObserver(self, selector: #selector(videoDidRotate), name: .UIDeviceOrientationDidChange, object: nil)
    }
    

    在观察者的方法中,调用setNeedsStatusBarAppearanceUpdate:

    func videoDidRotate() {
        self.setNeedsStatusBarAppearanceUpdate()
    }
    

    应该可以的。

    【讨论】:

    • 将它转换为 Objective-C 并且它就像一个魅力。谢谢。
    • 我在 iOS10 和 iOS11 上遇到了完全相同的问题,我花了一整天的时间试图修复它,直到我找到了这个解决方案。非常感谢您的回答。
    • 工作几乎完美,但是......当您在视频中点击“完成”,同时仍将设备保持在横向方向时,它不会显示状态栏,直到您将设备旋转回来成肖像。
    【解决方案2】:

    很简单,

    斯威夫特 3

    override func viewWillLayoutSubviews() {
       super.viewWillLayoutSubviews();
       UIApplication.shared.isStatusBarHidden = false
    }
    

    【讨论】:

    • 这应该是公认的答案。这是唯一对我有用的。
    • UIApplication.shared.isStatusBarHidden 已弃用
    【解决方案3】:

    @Aaron 的回答几乎可以工作,只有一个问题:当您在视频中点击“完成”时,仍将设备保持为横向,直到您将设备旋转回纵向时,它才会显示状态栏.

    在这种情况下,我在点击“完成”按钮时添加了通知观察者,然后我以编程方式切换到纵向。

    我的代码在 Objective C 中:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoDidRotate) name:UIDeviceOrientationDidChangeNotification object:nil];
    
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closedFullScreen:) name:UIWindowDidBecomeHiddenNotification object:nil];
    }
    
    -(void)closedFullScreen:(NSNotification *)myNotification{
        [[UIDevice currentDevice] setValue:
         [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
                                        forKey:@"orientation"];
    }
    
    - (BOOL)prefersStatusBarHidden {
        return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
    }
    
    - (void)videoDidRotate {
        [self setNeedsStatusBarAppearanceUpdate];
    }
    

    编辑:

    .plist 文件中基于视图控制器的状态栏外观必须设置为 YES。

    【讨论】:

    • 只是为了澄清这是在根控制器还是包含 YouTube 视图的控制器上?
    • 包含 YouTube 视图的控制器
    • 奇怪,它似乎对我不起作用。我的高度看起来像这样:控制器-> 容器-> 导航控制器-> 控制器-> YoutubeView。可能太复杂了,但改变 atm 有点太远了
    • .plist 文件中基于控制器的状态栏外观必须设置为 YES。
    • 这就是我的答案!谢谢!
    【解决方案4】:

    我尝试了@Makalele 的答案,但效果不佳(或者它可能会因为其他测试代码而被阻止)。经过一些测试和尝试,我最终得到了比这更简单的东西。

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self
                   selector:@selector(setNeedsStatusBarAppearanceUpdate)
                       name:UIDeviceOrientationDidChangeNotification
                     object:nil];
        [center addObserver:self
                   selector:@selector(setNeedsStatusBarAppearanceUpdate)
                       name:UIWindowDidBecomeHiddenNotification
                     object:nil];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    
    - (BOOL)prefersStatusBarHidden {
        return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
    }
    

    注意事项

    1. 您可以使用选择器直接调用setNeedsStatusBarAppearanceUpdate
    2. 在视图消失时添加了removeObserver 调用。
    3. prefersStatusBarHidden 的返回值必须不时更改。

    因此,在包含 YouTube 视图的视图控制器中,您会看到状态栏在进入 YouTube 全屏之前消失。它会在 YouTube 播放完成后返回(通过UIWindowDidBecomeHiddenNotification 事件)。

    万一这个事件没有触发,另一个事件:UIDeviceOrientationDidChangeNotification,仍然会在用户旋转屏幕时触发(即使方向被锁定)。

    所以,@Makalele 的解决方案有触发状态栏的双重路由。

    我发现我不需要UIDevice:setValue:forKey:,但您的里程可能会有所不同。

    感谢@Makalele 和@Aaron。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      相关资源
      最近更新 更多