横向模式下视频播放后状态栏下的导航栏

时间:2016-03-04 19:38:35

标签: ios objective-c iphone swift

问题:

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

申请表:

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

重现的设置:

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

    1. 当应用打开时
    2. when app opens

      1. 播放视频并将设备置于风景中
      2. enter image description here

        1. 问题:
        2. enter image description here

4 个答案:

答案 0 :(得分:20)

Swift 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()
}

应该这样做。

答案 1 :(得分:10)

这很简单,

swift 3

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

答案 2 :(得分:8)

@Aaron answer almost works, there's only one problem: when you tap "done" in the video, while still holding the device in landscape orientation, it won't show status bar until you'll rotate your device back into portrait.

In that case, I've added notification observer when "done" button is tapped and then I switch to portrait programmatically.

My code is in 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];
}

EDIT:

View controller-based status bar appearance in .plist file must be set to YES.

答案 3 :(得分:2)

我尝试了@ 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的返回值必须不时更改。
  4. 因此,在包含YouTube视图的视图控制器中,您会在进入YouTube全屏之前看到状态栏消失。它将在YouTube播放完成后返回(通过UIWindowDidBecomeHiddenNotification事件)。

    如果此事件未触发,另一个事件:UIDeviceOrientationDidChangeNotification,在用户旋转屏幕时仍会触发(即使方向已锁定)。

    所以,@ Makalele的解决方案有双重途径来触发状态栏。

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

    归功于@Makalele和@Aaron。