UIWebView in full screen hides status bar - iphone

I am opening video in UIWebView with following code.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"Navigatin Type %d %#",navigationType, request);
if (navigationType == 0) {
self.navigationItem.leftBarButtonItem = backBarBtn;
[self showVideoInWebView:[request.URL absoluteString]];
return NO;
}
return YES;
}
-(void)showVideoInWebView:(NSString *)urlStr
{
[mainWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]];
}
but when my mainWebView opens in full screen it hides my status bar.
I don't want to hide status bar
then how can I show my status bar?

You Can set Notification For making Status bar Visible.
Set The Notification for FullScreen Entry And Exit Notification ,SO that you could SHow And Hide The Status bar As Needed.
// For FullSCreen Entry
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoFullScreen:) name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
// For FullSCreen Exit
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoExitFullScreen:) name:#"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];
- (void)videoFullScreen:(id)sender
{
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
}
- (void)videoExitFullScreen:(id)sender
{
//Here do WHat You want
}
I am Sure It'll be helpful to you.

that is the behaviour of the built-in movie player AFAIK you cant change it ... maybe with an alternative HTML5 control.

when your UIWebView begin Fullscreen at that time write this line..
just try with this line..
-(void)moviePlayerEvent:(NSNotification*)aNotification{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
NSLog(#"%i", [UIApplication sharedApplication].statusBarHidden);
}

Another Way:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(VideoFullScreenExit:) name:UIWindowDidBecomeHiddenNotification object:self.view.window];
- (void)VideoFullScreenExit:(id)sender {
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}

Related

UIMoviePlayerControllerWillExitFullscreenNotification not received

My app is portrait only but, I would like to allow the user to rotate to landscape when watching full screen videos through a UIWebview. I've done some research and found that I should add my class as an observer for these notifications:
UIMoviePlayerControllerDidEnterFullscreenNotification
UIMoviePlayerControllerWillExitFullscreenNotification
I add and remove the class as an observer like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerDidEnterFullScreen:) name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillExitFullScreen:) name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
}
- (void)moviePlayerDidEnterFullScreen:(NSNotification *)notification
{
self.videoPlayingFullScreen = YES;
}
- (void)moviePlayerWillExitFullScreen:(NSNotification *)notification
{
self.videoPlayingFullScreen = NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
if (self.videoPlayingFullScreen)
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskPortrait;
}
My problem is: I never receive the "UIMoviePlayerControllerWillExitFullscreenNotification". I can't use the UIMoviePlayerControllerDidExitFullscreenNotification because if the user is finished watching the fullscreen video in landscape orientation and presses "done" the previous view controller also appears in landscape orientation when it should be in portrait.
Is there another way to detect when the user "did" enter fullscreen and "will" exit fullscreen? Or is there something that I am missing?
EDIT:
My app is for iOS 7 only.
The reason you're not getting the UIMoviePlayerControllerWillExitFullscreenNotification callback is because you're removing yourself as an observer on viewWillDisappear:
Since these callbacks are undocumented I used Javascript events (as H2CO3 suggested here) to determine when the video began, ended, or paused.
By the way I'm using the YouTube Player.
First, I setup the UIWebview and set my ViewController as the delegate.
Next, I loaded the HTML file into the UIWebview.
Index.html
<html>
<body bgcolor=#8C1717 style="margin:0px;">
<div id="ytplayer"></div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady()
{
player = new YT.Player('ytplayer',
{
height: 'videoHeight',
width: 'videoWidth',
videoId: 'videoID',
playerVars: { 'showinfo':0, 'rel':0 },
events: { 'onStateChange': onPlayerStateChange }
});
}
function playerDidBeginPlaying()
{
document.location.href = "fake://video-began";
}
function playerDidEndPlaying()
{
document.location.href = "fake://video-ended";
}
var done = false;
function onPlayerStateChange(event)
{
if (event.data == YT.PlayerState.PLAYING && !done)
{
done = true;
playerDidBeginPlaying();
}
else if (event.data == YT.PlayerState.ENDED)
{
playerDidEndPlaying();
}
else if (event.data == YT.PlayerState.PAUSED)
{
playerDidEndPlaying();
}
}
</script>
</body>
</html>
Inside the ViewController
NSError *error = NULL;
NSString *path = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (error)
{
#ifdef DEBUG
NSLog(#"[YouTube Webview] Error: %#", [error description]);
#endif
}
[self.webView loadHTMLString:html baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
Then, I implemented the method webView:shouldStartLoadWithRequest:navigationType: to get notified when the events happened.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([[[request URL] absoluteString] hasPrefix:#"fake://video-began"])
{
self.videoPlayingFullScreen = YES;
return NO;
}
else if ([[[request URL] absoluteString] hasPrefix:#"fake://video-ended"])
{
self.videoPlayingFullScreen = NO;
return NO;
}
return YES;
}

MPMoviePlayer not working properly

I have a problem regarding to MPMoviePlayer. I am using [self presentModalViewController:moviePlayer animated:YES]; to display player. When I click on Done button
(void) moviePlayBackDidFinish:(NSNotification*)notification
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
//[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
[self dismissModalViewControllerAnimated:YES];
//[self.view removeFromSuperview];
}
method calls. When it navigates to previous view, previous view's x and y ordinates get disturbed and everything is changed, means, the view gets changed. Any suggestions ?
Try using the methods presentMoviePlayerViewControllerAnimated: and dismisMoviePlayerViewControllerAnimated: instead of using presentModalViewController:animated: / dismissModalViewControllerAnimated:
Solved the problem by removing [[UIApplication sharedApplication] setStatusBarHidden:YES]; code.

Is it possible to check if done button is pressed

I have notification on movie player:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
And it's handler:
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// Remove observer
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
Here in this handler method I want to check if the done button is sender. Because I have two senders to this method. How ti check this?
Per docs: MPMoviePlayerPlaybackDidFinishNotification userInfo dictionary must contain NSNUmber for MPMoviePlayerPlaybackDidFinishReasonUserInfoKey key indicating the reason playback has finished. Its possible values:
enum {
MPMovieFinishReasonPlaybackEnded,
MPMovieFinishReasonPlaybackError,
MPMovieFinishReasonUserExited
};
You will first need to assign tag to your buttons before the action and then check the value of the sender tag.
Just add these lines of code:
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
NSInteger anyInteger = [sender tag];
//Now check the value of the anyInteger and write the code accordingly.
//switch case or if condition whatever you want.
}
That's it.
This is an old thread but I stumbled upon it while looking for a solution, and the accepted solution doesn't show the final code.
Here is what you have to do:
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
NSLog(#"moviePlayBackDidFinish");
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
NSInteger movieFinishReason= [[[notification userInfo]objectForKey:
MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if(movieFinishReason == 2 || movieFinishReason == 1 || movieFinishReason == 0){
[self dismissViewControllerAnimated:YES completion:nil];
}
/*
MPMovieFinishReasonPlaybackEnded = 0,//played movie sucessfuly.
MPMovieFinishReasonPlaybackError = 1, //error in playing movie
MPMovieFinishReasonUserExited = 2; //user quitting the application / user pressed done button
*/
}
Add tag with the button and put condition according to the tag.
Or check by
if([sender isEqual:btn1])
{
}
else
{
}

Why is the title bar appearing behind the status bar after a rotation?

I have a UIViewController whose view is a UIWebView with an embedded movie. When the movie is playing full screen, and the device is rotated, the title bar ends up behind the status bar after the movie is dismissed. Why might this happen?
Turns out that the animation of the view controller's view wasn't finished when the video started. This caused it to be redisplayed over the video player view.
My solution:
(void)viewDidLoad
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
[UIApplication sharedApplication].keyWindow.frame=CGRectMake(0, 20, 320, 460);
self.navigationController.navigationBar.hidden=NO;
}
did you autoresizingMask on the UIWebView
webView.autoresizingMask=(UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleWidth);
and
-(BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) orientation
{
return YES;
}
It's no way to resolve this problem using MPMoviePlayerNotification, because UIWebView Video Don't use MPMoviePlayerViewController or it's private for developer.
But, there's another way to fix this bug.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleStatusBarFrameDidChange)
name:UIApplicationDidChangeStatusBarFrameNotification
object:nil];
- (void)handleStatusBarFrameDidChange {
self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;
}

Overlay on top of Streaming MPMoviePlayerController

I went through the example from apple "MoviePlayer on iPhone"
Im trying to overlay on top of the mpmovieplayercontroller,
it works perfectly with video clip that is in bundle,
but it wont work if i stream the video from the url.
the overlay view will just get hide behind the player.
is there a way to bring the overlay view up to front?
MPMoviePlayerController creates its own window and sets that as the key window - you probably know this already from the MoviePlayer sample app.
I don't know why, but there's a delay when the player uses a stream - so the keyWindow you get right after you initialize the player is likely not the player's window, since that seems to get added later.
You can "cheat" and use a timer to get the player window a few seconds later, and add your overlay:
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(addMyOverlay:) userInfo:nil repeats:FALSE]
Or you can listen for the UIWindowDidBecomeKeyNotification event, and do the same:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyWindowChanged:) name:UIWindowDidBecomeKeyNotification object:nil];
Neither option is great (I'd love to know a cleaner way to do this), but it gets the job done.
You can overlay your view when you receive "MPMoviePlayerContentPreloadDidFinishNotification" notification.
Register for the notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadDidFinish:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:nil];
Add overlay view when receiving the notification:
// Notification called when the movie finished preloading.
- (void) moviePreloadDidFinish:(NSNotification*)notification
{
NSArray *windows = [[UIApplication sharedApplication] windows];
if ([windows count] > 1)
{
// Locate the movie player window
UIWindow *moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
if ([moviePlayerWindow viewWithTag:0x3939] == nil) {
self.videoOverlayView.tag = 0x3939;
[moviePlayerWindow addSubview:self.videoOverlayView];
}
[moviePlayerWindow bringSubviewToFront:self.videoOverlayView];
}
}
A very simple solution:
appDelegate.window.backgroundColor = [UIColor clearColor];
appDelegate.window.windowLevel = 2;
This will keep your app UI on top of the video window.
my post
Previous answer was based on timer. & fixed 5 seconds.
When Movie player begins, a new window is added to application.
Use a timer to check weather a new window is added to your application or not.
When a window ( movie player window ) is added. set notifications.
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadDidFinish:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:nil];
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
// Register to receive a notification when the movie scaling mode has changed.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieScalingModeDidChange:)
name:MPMoviePlayerScalingModeDidChangeNotification
object:nil];
videoListController.xmlClassVideoList=t;
// here ttttt is a timer declared in .h file
tttttt=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(startMy) userInfo:nil repeats:YES];
}
-(void)startMy{
NSArray *windows = [[UIApplication sharedApplication] windows];
NSLog(#"%i",[windows count]);
// depends on your application window
// it may be 1/2/3
if ([windows count] > 3) {
// Locate the movie player window
[tttttt invalidate];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyWindowChanged:) name:UIWindowDidBecomeKeyNotification object:nil];
}
}