Обнаруживать, когда веб-просмотр становится полноэкранным на ios8

У меня есть приложение, в котором пользователи могут открывать видео с 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, по мере того, как я тестировал.

Любая идея о том, что изменилось?

Ответ 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];

Ответ 2

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

Ответ 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")
}

Ответ 4

Ответ @NorthBlast хорошо работает для обнаружения любого UIWindow появляющегося поверх UIViewController который содержит UIWebView. К сожалению, трудно отфильтровать, что такое UIWindow (так как... ну, вы не можете действительно знать, это видео или какое-то другое окно).

Есть три специальных случая, которые я предпочитаю фильтровать, в которых вы уверены, что они НЕ являются окнами видеоплеера, это:

1) _UIAlertControllerShimPresenterWindow, который является видом окна, которое появляется при использовании предупреждений (например, UIAlertView).

2) UITextEffectsWindow, который появляется при представлении специальных окон iOS (например, в окне share, 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 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 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)