My whole application is in portrait mode only and i am playing youtube video in my application. For you tube I am using UIWebview. When user click on play button in UIWebview it automatically launch the MPMoviePlayerController. So I did not declared any MPMoviePlayerController object. So I want MPMoviePlayerController support both portrait and landscape orientation. So please suggest.
If you use NavigationController, you could subclass it and do the following:
#import "MainNavigationController.h"
#import <MediaPlayer/MediaPlayer.h>
#implementation MainNavigationController
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if ([[[self.viewControllers lastObject] presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return UIInterfaceOrientationMaskAll;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
#end
Then you should set your app to support all orientations, and this code will allow orientation change only if it is playing your movie 'MPMoviePlayerController`.
When calling your movie you should send a notification, so if user closes it in any orientation other than portraitit switches back to portrait.
Something like this:
- (IBAction)playButton:(id)sender {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackDidFinish)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.player.moviePlayer];
NSURL *url = [NSURL URLWithString:videoUrl];
self.player = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
self.player.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[self presentMoviePlayerViewControllerAnimated:self.player];
}
-(void)moviePlaybackDidFinish
{
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:#"orientation"];
}
This should do it for you, let me know how it goes.
Related
I use XCDYouTubeKit library for my iOS project. I present video from nonFullScreen mode with code:
self.videoPlayer = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:self.youtubeID];
[self.videoPlayer presentInView:self.videoView];
[self.videoPlayer.moviePlayer play];
When iPhone rotate to landscape mode i set FullScreen video with catching rotate current ViewController:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if (fromInterfaceOrientation == UIDeviceOrientationPortrait) {
[self.videoPlayer.moviePlayer setFullscreen:YES animated:NO];
}
But how i can catch rotation XCDYouTubeVideoPlayerViewController in fullScreen video mode??
Thank
My decision
in this class i add in viewDidLoad observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleDidChangeStatusBarOrientationNotification:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
And execution
- (void)handleDidChangeStatusBarOrientationNotification:(NSNotification *)notification; {
if ([self.videoPlayer.moviePlayer isFullscreen] && [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
[self.videoPlayer.moviePlayer setFullscreen:NO animated:YES];
}
}
I think the easiest way to get this information is to subclass XCDYouTubeVideoPlayerViewController and override didRotateFromInterfaceOrientation: and/or viewWillTransitionToSize:withTransitionCoordinator:
My app accepts only portrait orientation, except for MPMoviePlayerController, which I want to allow user to change orientation.
So, I subclassed UINavigationController and added the following code:
-(BOOL)shouldAutorotate
{
if ([[[self.viewControllers lastObject] presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return YES;
}
else
{
return NO;
}
}
It works great, allowing only my MPMoviePlayerViewController to change orientation. The problem is that when user is in landscape orientation and presses the done button or playback ends, it pops the moviePlayer and goes back to the presentingViewController, but on landscape mode, causing a crash, since that view is not made for landscape orientation.
I tried a few things to change back to Portrait but had no luck. I'm using storyboards, if that makes any difference. I would like to change the orientation back to portrait on viewWillAppear, or maybe getting the donebutton press and change the orientation there.
UPDATE:
Here is the updated code in my UINavigationControllersubclass:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if ([[[self.viewControllers lastObject] presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return UIInterfaceOrientationMaskAll;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
Now, if I do things in the following order from the view with the Play button.
Rotate the device. (it calls the method but screen doesn't rotate since it is not MPMoviePlayerController class)
Press the play button. (It presents the player already on landscape mode).
Press the back button. (It pops the player and correctly shows the view on portrait mode)
Now, if I change the order to:
Press the play button. (holding the device on the regular portrait position).
Rotate the device. (it rotates the movie player correctly showing the video).
Press the back button. (it pops the player, but this time, the view is in landscape mode, which is not the expected behavior)
Found a solution here on this answer.
On button click, I added a notification and then on done button click I used the below code to change orientation. I kept the UINavigationController subclass as in my question to allow the change of orientation when movie starts playing.
- (IBAction)playButton:(id)sender {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackDidFinish)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.player.moviePlayer];
NSURL *url = [NSURL URLWithString:#"https://dl.dropboxusercontent.com/s/crzu6yrwt35tgej/flexao.mp4"];
self.player = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
self.player.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[self presentMoviePlayerViewControllerAnimated:self.player]; // presentMoviePlayerViewControllerAnimated:self.player];
}
-(void)moviePlaybackDidFinish
{
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:#"orientation"];
}
I have a working configuration for your problem, as far as I understand from your question.
You need a subclass of UINavigationController as you already have, but with the following code:
The .h file:
#interface EECNavigationController : UINavigationController
#property (assign, nonatomic) BOOL landscapeDisallowed;
#end
The .m file:
#import "EECNavigationController.h"
#implementation EECNavigationController
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if( !_landscapeDisallowed ) {
// for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
#end
Now, in the view controllers that will be under this navigation controller that you want to be just portrait you just need to set the "landscapeDisallowed" to YES in the viewDidLoad method, like:
- (void)viewDidLoad {
[super viewDidLoad];
((EECNavigationController *)self.navigationController).landscapeDisallowed = YES;
}
And override the following methods like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
The views that can be presented in landscape mode just need to:
- (void)viewDidLoad {
[super viewDidLoad];
((EECNavigationController *)self.navigationController).landscapeDisallowed = NO;
}
It works for me, hope it works for you.
-(void)viewWillAppear:(BOOL)animated
{
[self updateLayoutForNewOrientation:self.interfaceOrientation];
}
- (void)updateLayoutForNewOrientation:(UIInterfaceOrientation)orientation
{
if (self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
// Portrait view
if(iPhone5)
{
}else{
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
}
}
else
{
// Landscape view
if(iPhone5)
{
}else{
float SystemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(SystemVersion>=7.0f)
{
}else{
}
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
if(iPhone5)
{
}
else
{
}
}
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
[self updateLayoutForNewOrientation:self.interfaceOrientation];
}
Hope this will help
I am working with an app which required to open "MPMoviePlayerViewController" when clicked on a video file.
There is a tabbarController into our app which has four Navigation controllers for four tabs.
My app only support portrait orientation, but video should support both landscape & portrait orientations. So, I make Subclass of "MPMoviePlayerViewController".
Code of that class..
#interface MyMovieViewController : MPMoviePlayerViewController
#end
#implementation MyMovieViewController
-(void)viewDidLoad{
[self setWantsFullScreenLayout:NO];
}
-(void)viewWillDisappear:(BOOL)animated{
[self resignFirstResponder];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
-(BOOL)shouldAutorotate{
return YES;
}
#end
In First tab, I show Gallery. There is a code to open video file.
UIGraphicsBeginImageContext(CGSizeMake(1,1));
MPMoviePlayerViewController * vc = [[MyMovieViewController alloc] initWithContentURL:[[[elcAsset asset] valueForProperty:ALAssetPropertyURLs] valueForKey:[[[[elcAsset asset] valueForProperty:ALAssetPropertyURLs] allKeys] objectAtIndex:0]]];
UIGraphicsEndImageContext();
// Remove the movie player view controller from the "playback did finish" notification observers
[[NSNotificationCenter defaultCenter] removeObserver:vc
name:MPMoviePlayerPlaybackDidFinishNotification
object:vc.moviePlayer];
// Register this class as an observer instead
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(doneButtonClick:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: vc.moviePlayer];
[self presentMoviePlayerViewControllerAnimated:vc];
[vc.moviePlayer prepareToPlay];
[vc.moviePlayer play];
Video is working file. It also support both orientations. but when I switch to another tab, then no textfield show keyboard when clicked on it.
Please help. Thanks is advance.
I have solved the issue.
Actually, MPMoviePlayerViewController support both orientations and my app support only portrait. When i dismiss MPMoviePlayerViewController,then parentview of it think that it is Landscape mode.
So, it display landscape keyboard, which's CGPoint is lower than screen. Thats why I am not able to see keyboard.
I have make write following code into my CustomNavigationController.
- (BOOL)shouldAutorotate
{
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.visibleViewController supportedInterfaceOrientations];
}
Now, it is working fine.
YOu need to dismiss Your MoviePlayer..
Use this notification that calls when your video is over
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.theMoviePlayer];
and write method of it.
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{
[self dismissMoviePlayerViewControllerAnimated];
MPMoviePlayerController* theMovie = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie];
}
You can try this delegate method,
(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{
[myTextField becomeFirstResponder];
return YES;
}
If this does not work, try to find out what is called after dismissing the view and then insert following code... This will definitely work.
[myTextField becomeFirstResponder];
I have an application entirely in portrait mode. (iOS 5 and above)
I have a video played using MPMoviePlayerController, now in this video i want that when user rotates the iPhone, the video should go to landscape mode(in fullscreen).
When video ends , again the video should go into portrait mode.
Code:
-(void)PlayVideo:(NSURL*)videoUrl
{
moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:videoUrl];
[moviePlayerController.view setFrame:CGRectMake(6, 69, 309, 196)];
[self.view addSubview:moviePlayerController.view];
// moviePlayerController.fullscreen = YES;
moviePlayerController.controlStyle = MPMovieControlStyleNone;
[self.view bringSubviewToFront:self.shareView];
[self.view bringSubviewToFront:self.qualityView];
[moviePlayerController play];
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
}
Rest of the app, i want in portrait only.
How do i achieve this?
First you need to set Support interface orientation to Portrait as well as Landscape
Now in every UIViewController you need to override these methods -
for iOS 5 -
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate
{
return NO;
}
for iOS 6
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
In UIViewController where you are going to add MPMoviePlayerController override -
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
I created Xcode project with sample of the video player. It can show video on full screen in landscape mode. You can download it . I hope it helps you.
And second. Instead of
[self.view bringSubviewToFront:self.shareView];
[self.view bringSubviewToFront:self.qualityView];
you should write like this:
[moviePlayerController.view insertSubview: self.shareView
atIndex: 2];
[moviePlayerController.view insertSubview: self.qualityView
atIndex: 2];
then shareView and qualityView appears on top of the movie player.
I am working on a app in which I have a list of items where i want to click on a thumbnail and video must be played, My requirement is Only MPMovieViewController must rotate remaining screens must not rotate for this I am using below method in list to make it portrait every time. But if i am using it i am not able to rotate the MPMoviePlayerViewController.
- (NSUInteger)supportedInterfaceOrientations{
return (UIInterfaceOrientationMaskPortrait);
}
So i returned "UIInterfaceOrientationMaskAll" after returning i am able to Autorotate the MPMoviePlayerViewController But when i come back clicking on done Button or after video is done when video is in landscape mode then my previous is rotating but i dont want that behaviour i need the previous view in portrait, Below is code for implementing the MPMoviePlayerViewContoller.
NSString *filepath = [[NSBundle mainBundle] pathForResource:[exeDict objectForKey:#"longVideoName"] ofType:#"mp4"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:fileURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController.moviePlayer];
[moviePlayerController.view setFrame:CGRectMake(0, 0, 320, 480)];
moviePlayerController.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
moviePlayerController.view.userInteractionEnabled =YES;
[moviePlayerController shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationMaskAll];
// AppDelegate* myDelegate = (((AppDelegate*) [UIApplication sharedApplication].delegate));
// [myDelegate.window addSubview:moviePlayerController.view];
MainViewController* mainViewController = (MainViewController*)self.mainViewDelegate;
[mainViewController presentMoviePlayerViewControllerAnimated:moviePlayerController];
[moviePlayerController.moviePlayer play];
Please let me know how to get it.
you will have have to put code in viewwillappear() method so that your list appears in portrait mode
- (BOOL)shouldAutorotate
{
return NO;
}
Implemented above code in mainViewController??