Correctly force or enable landscape mode for embedded Youtube video in iOS 8 without NSNotificationCenter

I am having trouble capturing when the YouTube player enters full screen mode or exits full screen mode in iOS 8 because these notifications were deleted by UIMoviePlayerControllerDidEnterFullscreenNotification and UIMoviePlayerControllerWillExitFullscreenNotification for this OS version.

Since my application project is installed only in portrait mode, the video will not rotate in landscape mode when it is playing, which is really not very convenient for watching video on your device.

Typically, the user wants to watch the video in portrait mode or landscape mode when the video enters full screen mode.

This is how I did it for iOS 7 , which worked fine, but not in iOS 8.

First I will install this function in my AppDelegate.m with a boolean property in my AppDelegate.h , which I called videoIsInFullscreen and function,

 // this in the AppDelegate.h @property (nonatomic) BOOL videoIsInFullscreen; // This in my AppDelegate.m to allow landscape mode when the boolean property is set to yes/true. - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ if(self.videoIsInFullscreen == YES) { return UIInterfaceOrientationMaskAllButUpsideDown; } else { return UIInterfaceOrientationMaskPortrait; } } 

Then in my ViewController.m First I would #import "AppDelegate.h" do this, add some notifications to my viewDidLoad method.

 -(void)viewDidLoad { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerStarted) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerEnded) name:@"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil]; } 

Of course, do not forget to delete them.

 -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil]; } 

Then I had my functions, which will receive a call when these notifications receive fires ... This is where I enable landscape mode, and then return to the portrait. This is the case with my application, because it is configured only for portrait support, but I do not want this for a YouTube video.

 // first we set our property in the our AppDelegate to YES to allow landscape mode - (void)playerStarted { ((AppDelegate*)[[UIApplication sharedApplication] delegate]).videoIsInFullscreen = YES; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; } // Then I will set the property to NO and force the orientation to rotate to portrait. - (void)playerEnded { ((AppDelegate*)[[UIApplication sharedApplication] delegate]).videoIsInFullscreen = NO; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; } 

But this does not apply to iOS 8 .. These notifications no longer work for iOS 8, so I found something similar using these notifications, but I'm not too happy because they are not 100% accurate for the video player. UIWindowDidBecomeVisibleNotification and UIWindowDidBecomeHiddenNotification So, how can I do it right or at least work correctly for the embedded YouTube video and enable landscape mode in iOS 8 ...?

+5
source share
2 answers

So, after some research and a deeper study of this problem .. I came up with a solution using UIWebView delegates, plus I had to solve another problem in terms of my function - (void)playerEnded , which wasn’t working correctly in new devices iPhone 6

Here is how I did it. First, in my webViewDidFinishLoad method, I added a javascript rating to my webViewDidFinishLoad to check when this video player goes into full screen mode.

 - (void)webViewDidFinishLoad:(UIWebView*)webView { // adding listener to webView [_webView stringByEvaluatingJavaScriptFromString:@" for (var i = 0, videos = document.getElementsByTagName('video'); i < videos.length; i++) {" @" videos[i].addEventListener('webkitbeginfullscreen', function(){ " @" window.location = 'videohandler://begin-fullscreen';" @" }, false);" @"" @" videos[i].addEventListener('webkitendfullscreen', function(){ " @" window.location = 'videohandler://end-fullscreen';" @" }, false);" @" }" ]; } 

Then, in my method - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType , I check when my request URL matches the state of youtube player, for example. This will launch our function to enable landscape mode or return to portrait mode .. or perhaps any other type of work that you might want to do.

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { // allows youtube player in landscape mode if ([request.URL.absoluteString isEqualToString:@"ytplayer://onStateChange?data=3"]) { [self playerStarted]; return NO; } if ([request.URL.absoluteString isEqualToString:@"ytplayer://onStateChange?data=2"]) { [self playerEnded]; return NO; } } 

And finally, I needed to set up the playerEnded function to force portrait mode back on for iPhone 6 devices.

 - (void)playerEnded { [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"]; ((AppDelegate*)[[UIApplication sharedApplication] delegate]).videoIsInFullscreen = NO; [self supportedInterfaceOrientations]; [self shouldAutorotate:UIInterfaceOrientationPortrait]; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; } 

Almost, a missed I also added these two other functions.

 - (NSInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (BOOL)shouldAutorotate:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } 

So, finally, I can catch the state of a real player and run my functions to do some kind of work or something that I want at the right time, in my case, changing orientation.

Hope this helps someone else.

+3
source

I work fast, I play a movie in both portrait and landscape directions. First, I checked three modes: portrait, landscape, landscape. Second, I wrote this function in all viewController:

  isFullScreen = false override func shouldAutorotate() -> Bool { if isFullScreen == true { return true }else{ return false } } 

Thirdly, I change the value of isFullScreen in this function:

 func playerView(playerView: YTPlayerView!, didChangeToState state: YTPlayerState) { switch (state) { case YTPlayerState.Playing: println("started to play") isFullScreen == true shouldAutorotate() case YTPlayerState.Paused: println("paused") default: println("non of sttate") break } } 

And the video works both in portrait and landscape modes! Interestingly, I do not set isFullScreen to false again when I pause the video or switch from full screen mode. However, it does not spin! Can someone explain this?

0
source

Source: https://habr.com/ru/post/1202317/


All Articles