Disappearing status bar at the top after MPMoviePlayerController is closed - objective-c

Having an interesting little problem with my iPhone app. I have a view with a table and each cell, when clicked, plays a video fullscreen then when you press done, the video stops and goes back to the table view. The only problem is, when you press done within the first 2 or 3 seconds of the video loading, when the view goes back to the table view, the bar at the top of the screen that tells the time and battery strength etc is no longer there, its just a white space. But if you press done after the first few seconds, then when you go back to the table view, everything is absolutely fine! I have absolutely no idea why this is happening and the only thing I found on the internet is this which is some guy with pretty much exactly the same problem as me:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/53020-disappearing-status-bar.html
This lead me to try using:
[UIApplication sharedApplication].statusBarHidden = NO;
However this lead nowhere either.
The code that is executed when they click on a video:
NSString *path = [[NSBundle mainBundle] pathForResource:currentTitle ofType:#"m4v"];
NSURL *url = [NSURL fileURLWithPath:path];
movieController = [[MPMoviePlayerController alloc] initWithContentURL:url];
[movieController setControlStyle:MPMovieControlStyleFullscreen];
[movieController setFullscreen:YES];
movieController.view.frame = self.view.bounds;
[self.view addSubview:movieController.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
And the code that executes either when the video is done or when the user clicks done is:
NSLog(#"movieController moviePlayBackDidFinish");
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[movieController setFullscreen:NO animated:NO];
[movieController.view removeFromSuperview];
[movieController release];
LiveEventsView *liveEventsView = [[LiveEventsView alloc] initWithNibName:#"LiveEventsView" bundle:nil];
UIView *currentView = self.view;
UIView *theWindow = [currentView superview];
UIView *newView = liveEventsView.view;
newView.frame = CGRectMake(0, 20, 320, 460);
[currentView removeFromSuperview];
[theWindow addSubview:newView];
[UIApplication sharedApplication].statusBarHidden = NO;
If anybody can shed any light on this situation, I would be very grateful as it is extremely frustrating!
Thanks,
Matt

Maybe the animation from when the video view disappears is causing a timing issue with the status bar animation.
try delaying the statusBarHidden = NO call by a few seconds.
NSInteger delay = 3;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
[UIApplication sharedApplication].statusBarHidden = NO;
});

You can just set the delay to be a float instead. So it would be
float delay = 0.1;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
[UIApplication sharedApplication].statusBarHidden = NO;
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackOpaque;
});
I had the same problem and solved it by modifying richerd's code a bit. 0.1 second is acceptable imo. I also had to change the status bar style since it returned a BlackTranslucent bar style and the original was BlackOpaque style. But works fine now.

I've found that with the given solutions the content often disappears beneath the status bar. This approach fixes it.
Register for MPMoviePlayerWillExitFullscreenNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerWillExitFullscreen:)
name:MPMoviePlayerWillExitFullscreenNotification
object:self.moviePlayer];
And then reset the status bar visibility AND remove and re-add the rootViewController from the main window, this will make sure that the bounds of the view are correct again.
- (void)moviePlayerWillExitFullscreen:(NSNotification *)notification {
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
id rootViewController = appDelegate.window.rootViewController;
appDelegate.window.rootViewController = nil;
appDelegate.window.rootViewController = rootViewController;
}

Related

Objective C : How to Insert text in Movie Player View?

I am making a Apache Cordova Application.
On this Application, I used the plugin : Cordova Streaming Media plugin
Link is : https://github.com/nchutchind/Streaming-Media-Cordova-Plugin
I want to insert a "Hello World!" label on my movie but I don't know how to do that.
I think the script is : StreamingMedia.m
Link is : https://github.com/nchutchind/Streaming-Media-Cordova-Plugin/blob/master/src/ios/StreamingMedia.m
And function is : startPlayer()
Can you tell me where is my error :
-(void)startPlayer:(NSString*)uri {
NSURL *url = [NSURL URLWithString:uri];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
// Listen for playback finishing
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
// Listen for click on the "Done" button
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(doneButtonClick:)
name:MPMoviePlayerWillExitFullscreenNotification
object:nil];
// Listen for orientation change
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;
if (imageView != nil) {
[moviePlayer.backgroundView setAutoresizesSubviews:YES];
[moviePlayer.backgroundView addSubview:imageView];
}
moviePlayer.backgroundView.backgroundColor = backgroundColor;
[self.viewController.view addSubview:moviePlayer.view];
// Note: animating does a fade to black, which may not match background color
[moviePlayer setFullscreen:YES animated:NO];
// Here my code :
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 0, 0)];
label.text = #"Hello World!";
CGRect frame = label.frame;
frame.origin.x = 100;
frame.origin.y = 50;
label.frame = frame;
[self.viewController.view addSubview:label];
}
Thank You!
You have two choices:
You can add a view to the app window/root controller view.
Create custom controller and add to his view MPMoviePlayerController like
subView.
Errors:
Your UILabel has 0x0 sizes. Just set up sizes :)
You send _rangeSlider to back of view via sendSubviewToBack. Remove it and it's start working.
And it seems you can just add subview to the MPMoviePlayerController view.

MPMoviePlayerController and let the user replay

I have an iOS app with a MPMoviePlayerController, I need to play a video from an URL. Everything seems to work fine, but when the playback ends the MPMoviePlayerController shows a weird image and it takes AGES to replay the video...
This is what I have so far:
mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateChanged:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
And the moviePlayerLoadStateChanged and moviePlayBackDidFinish look like this:
- (void) moviePlayerLoadStateChanged:(NSNotification*)notification
{
if ([mp loadState] != MPMovieLoadStateUnknown)
{
[[NSNotificationCenter defaultCenter]removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
[mp setControlStyle:MPMovieControlStyleEmbedded];
[mp setFullscreen:NO];
[mp.view setFrame:CGRectMake(10, 54, 300, 200)];
[mp setShouldAutoplay:NO];
[mp prepareToPlay];
[[self view] addSubview:[self.mp view]];
}
}
I don't know what that Image is, but I would like to replace it... also I think it takes so much because it's loading the video from a URL, I don't know how to add a loading, or a spinner... Any idea?
You could set the repeatMode property of your MPMoviePlayerController to MPMovieRepeatModeOne
by using:
mp = [[MPMoviePlayerViewController alloc]
initWithContentURL:[NSURL fileURLWithPath:path]];///Put your path to your resource
mp.moviePlayer.repeatMode = MPMovieRepeatModeOne;
I hope this helps if i understood your question correctly.
If not i recommend checking out the documentation HERE
Happy coding:)

disable user interaction in MPMoviePlayerController

I need to disable total user interaction during a play of a litle video, i already tried to set the style of the control to none : MPMovieControlStyleNone, and put a UIView above the MPMoviePlayerController, but when i pinch the video disappears, and the sound still playing, like i dismissed the video, but it still playing on the background, plus the user interaction is disabled.
Heres how i do:
-(IBAction)startGame:(id)sender
{
NSURL * url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Teste" ofType:#"m4v"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.shouldAutoplay = YES;
[self.view addSubview:moviePlayer.view];
[moviePlayer setFullscreen:YES animated:YES];
mBlankView = [[UIView alloc] initWithFrame:moviePlayer.view.frame];
mBlankView.userInteractionEnabled = NO;
[mBlankView setMultipleTouchEnabled:NO];
[mBlankView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:mBlankView];
}
To disable Movieplayer control completely u need to disable your movieplayers view userinteraction as follows:
moviePlayer.view.userInteractionEnabled = NO;

MFMessageComposeViewController not properly displayed

I'm using MFMessageComposeViewController in order to show the SMS send interface.
My app uses full screen, the status bar is hidden by settings in plist file (Status bar is initially hidden = YES).
When I show the message composer with:
+(void)composeSMS:(id)sender
{
if (![MFMessageComposeViewController canSendText]) return;
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
controller.wantsFullScreenLayout = YES;
controller.messageComposeDelegate = sender;
[controller setBody:#"He descubierto un App estupenda! . "];
[controller setModalPresentationStyle:UIModalTransitionStyleFlipHorizontal];
if (controller) [sender presentModalViewController:controller animated:YES];
[controller release];
}
The problem is when the composer is displayed the navigation bar is on the top y = 0, but between this bar and the rest of outlets of the view appears an empty space of the same size as the status bar. The status bar is showed in this screen (second issue) but is overlapping the navigation bar of the composer view.
In other projects where the status bar is not hidden, this works like a charm. But this is the first project where it is used without status bar and this is happening.
Anyone knows how to fix it?
Thanks.
Hide the status bar after you modal presented the message controller. Something like this:
controller.wantsFullScreenLayout = NO;
[self presentModalViewController:controller animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
The way I dealt with using iMessage inside an app was to take control of the status bar myself.
For example:
[[UIApplication sharedApplication] setStatusBarHidden:FALSE withAnimation:UIStatusBarAnimationSlide];
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:TRUE];
[controller release];
Then when finished either through a send or a cancel:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
[self dismissModalViewControllerAnimated:TRUE];
[[UIApplication sharedApplication] setStatusBarHidden:TRUE withAnimation:UIStatusBarAnimationSlide];
self.view.frame = CGRectMake(0.0, 0.0, [LayoutHelper width], [LayoutHelper height]);
self.view.center = CGPointMake([LayoutHelper xCenterPoint], [LayoutHelper yCenterPoint]-20);
}
This seems to display the iMessage and then return to the app without any empty space appearing from the status bar being added or removed.
This is my first post so i hope this helps somehow.
cheers

MPMoviePlayerController controls when opened in a UIModalPresentationFormSheet style modal and the user makes the video fullscreen

In my iPad app, I have a UIButton that is calling an IBAction to call a view controller as a modal to show a video in. I wanted the modal to appear as 720x405, and that part seems to work out okay. Here is the IBAction code the button is executing:
-(IBAction)videoPlayerTest:(id)sender {
VideoModalViewController *vc = [[VideoModalViewController alloc] initWithNibName: #"VideoModalViewController" bundle: nil];
vc.fileName = #"testvideo.m4v";
vc.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:vc animated: YES];
vc.view.superview.frame = CGRectMake(0, 0, 720, 405);
vc.view.superview.center = self.view.center;
[vc release];
}
The modal comes up where I want it, and the controls respond on the MPMoviePlayerController; the jog bar, pause, play, etc. but if the user taps on the fullscreen button, the video does go fullscreen alright, but after that the MPMoviePlayerController won't respond to any subsequent taps on the player controls. If I remove the modalPresentationStyle line it will work, but the modal appears on a fullscreen view instead of the 720x405 modal like I want. I've added Observers to try resizing the frame and recenter it when the user makes the movie controller fullscreen and back to windowed, but it didn't appear to help at all. Here is that code.
- (void)willEnterFullscreen:(NSNotification*)notification {
NSLog(#"willEnterFullscreen");
[self setModalPresentationStyle:UIModalPresentationFullScreen];
self.view.frame = CGRectMake(0, 0, 1024, 768);
self.view.center = self.view.center;
}
- (void)willExitFullscreen:(NSNotification*)notification {
NSLog(#"willExitFullscreen");
[self setModalPresentationStyle:UIModalPresentationFormSheet];
self.view.frame = CGRectMake(0, 0, 720, 405);
self.view.center = self.view.center;
}
- (void)playMovie {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
NSString *videoString = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
NSURL *videoURL = [NSURL fileURLWithPath:videoString];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
[self.view addSubview:moviePlayer.view];
moviePlayer.view.frame = CGRectMake(0, 0, 720, 405);
moviePlayer.view.backgroundColor = [UIColor grayColor];
[moviePlayer prepareToPlay];
[moviePlayer play];
}
This is my first post-- hope I did it right and provided enough information about the problem I'm having.
I've solved my problem. I was unaware of MPMoviePlayerViewController and I created that and used that as my modal instead. It works great.
-(void)playVideo:(NSString *)fileName {
NSString *videoString = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
NSURL *videoURL = [NSURL fileURLWithPath:videoString];
mpViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[self presentModalViewController:mpViewController animated:NO];
[[mpViewController moviePlayer] play];
}
-(IBAction)videoPlayerTest:(id)sender {
[self playVideo:#"testvideo.m4v"];
}
Thought I'd post what I came up with just in case somebody else encounters the same