【问题标题】:Detect when a webview video becomes fullscreen on ios8检测 webview 视频何时在 ios8 上变为全屏
【发布时间】:2014-11-04 03:47:49
【问题描述】:

我有一个应用程序,用户可以在其中打开 UIWebview 的视频,包括 Youtube 视频。 在 iOS7 中,我能够在开始播放或全屏播放时收到通知,这对我向用户显示某些选项和修改界面至关重要。

我以前用这个:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoExitFullScreen:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoEnterFullScreen:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];

但是,从 iOS8 开始,我无法做到这一点。就像 UIWebview 视频不再触发通知一样。但是,正如我测试过的,它仍然是由普通视频、非 Webview 触发的。

知道发生了什么变化吗?

【问题讨论】:

    标签: ios video uiwebview youtube mpmovieplayercontroller


    【解决方案1】:

    这是我为此找到的解决方法..

    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(VideoExitFullScreen:)
                                                     name:UIWindowDidBecomeVisibleNotification
                                                   object:self.view.window];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(VideoEnterFullScreen:)
                                                     name:UIWindowDidBecomeHiddenNotification
                                                   object:self.view.window];
    

    【讨论】:

    • 我发现当视频开始全屏播放时会调用 UIWindowDidBecomeVisibleNotification。当视频消失时调用 UIWindowDidBecomeHiddenNotification
    • 我正在 iOS 10 中尝试这个,但这些通知从来没有被我调用过。其他人有同样的问题吗?
    • @BerryBlue 是的。同样的问题。你有没有找到其他方法?
    • @BerryBlue 删除对象:self.view.window,并替换为对象:nil]
    【解决方案2】:

    斯威夫特 5.1:

    NotificationCenter.default.addObserver(
        forName: UIWindow.didResignKeyNotification,
        object: self.view.window,
        queue: nil
    ) { notification in
        print("Video is now fullscreen")
    }
    
    NotificationCenter.default.addObserver(
        forName: UIWindow.didBecomeKeyNotification,
        object: self.view.window,
        queue: nil
    ) { notification in
        print("Video stopped")
    }
    

    【讨论】:

    • 好吧,它不适用于UIWebView 内的 YouTube iFrame。它总是调用成为全屏或存在全屏的两个事件
    • 因为我们应该使用didBecomeVisibleNotificationdidBecomeHiddenNotification
    • Swift 5 ``` NotificationCenter.default.addObserver(forName: UIWindow.didResignKeyNotification, object: self.view.window, queue: nil) { _ in print("Video is now fullscreen") } NotificationCenter.default.addObserver(forName: UIWindow.didBecomeKeyNotification, object: self.view.window, queue: nil) { _ in print("视频停止") } ``
    • 为 swift 5 更新
    【解决方案3】:

    Swift 4.2、iOS 12.1 和 WKWebView 的更新:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        // listen for videos playing in fullscreen
        NotificationCenter.default.addObserver(self, selector: #selector(onDidEnterFullscreen(_:)), name: UIWindow.didBecomeVisibleNotification, object: view.window)
    
        // listen for videos stopping to play in fullscreen
        NotificationCenter.default.addObserver(self, selector: #selector(onDidLeaveFullscreen(_:)), name: UIWindow.didBecomeHiddenNotification, object: view.window)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    
        // remove video listeners
        NotificationCenter.default.removeObserver(self, name: UIWindow.didBecomeVisibleNotification, object: view.window)
        NotificationCenter.default.removeObserver(self, name: UIWindow.didBecomeHiddenNotification, object: view.window)
    }
    
    @objc func onDidEnterFullscreen(_ notification: Notification) {
        print("video is now playing in fullscreen")
    }
    
    @objc func onDidLeaveFullscreen(_ notification: Notification) {
        print("video has stopped playing in fullscreen")
    }
    

    【讨论】:

    • 对象:view.window 有时意味着通知不会被观察到。我们可以为对象参数传递 nil,以始终接收通知。
    【解决方案4】:

    @NorthBlast 的答案非常适合检测出现在包含UIWebViewUIViewController 顶部的任何UIWindow。不幸的是,很难过滤出UIWindow 是什么类型的(因为,嗯......你无法真正知道它是视频还是其他类型的窗口)。

    我更喜欢过滤 3 种特殊情况,您确定它们是不是视频播放器窗口,它们是:

    1) _UIAlertControllerShimPresenterWindow,这是一种在使用警报时出现的窗口(如UIAlertView)。

    2) UITextEffectsWindow,在呈现特殊的 iOS 窗口时出现(如共享窗口,UIActivityViewController)。

    3) UIRemoteKeyboardWindow 在展示键盘时出现(由于某种原因,这个类只在我使用 Swift 时出现,但在 Objective-C 上却没有......不知道为什么会这样)。

    所以要订阅通知,我使用(就像@NorthBlast 所说):

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(windowDidBecomeActive:)
                                                 name:UIWindowDidBecomeVisibleNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(windowDidBecomeHidden:)
                                                 name:UIWindowDidBecomeHiddenNotification
                                               object:nil];
    

    然后是实现:

    - (void)windowDidBecomeActive:(NSNotification *)notification {
        if ( [self isVideoPlayerWindow:notification.object] ) {
            // Do what's needed if it is a video
            // For example, on a live streaming radio app, I would stop the audio if a video is started
        }
    }
    
    - (void)windowDidBecomeHidden:(NSNotification *)notification {
        if ( [self isVideoPlayerWindow:notification.object] ) {
            // Do what's needed if it is a video
        }
    }
    
    - (BOOL)isVideoPlayerWindow:(id)notificationObject {
        /*
         Define non video classes here, add more if you need it
        */
        static NSArray *nonVideoClasses = @[
            @"_UIAlertControllerShimPresenterWindow",
            @"UITextEffectsWindow",
            @"UIRemoteKeyboardWindow"
        ];
    
        BOOL isVideo = YES;
        for ( NSString *testClass in nonVideoClasses ) {
            isVideo = isVideo && ! [notificationObject isKindOfClass:NSClassFromString(testClass)];
        }
    
        return isVideo;
    }
    

    【讨论】:

      【解决方案5】:

      对于快速:

      NotificationCenter.default.addObserver(self, selector: #selector(xxx), name: NSNotification.Name.MPMoviePlayerDidExitFullscreen, object: nil)

      【讨论】:

      • 这将不再适用于 iOS 9 等。现在已弃用。
      猜你喜欢
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      相关资源
      最近更新 更多