Cocos 2d 2.0 shouldAutorotate not working? - iphone

I'm having some issues. I have a cocos2d game I'm just about done developing. However I've run into a problem where I need to enable portrait orientation in my apps plist for game center sign in to work without throwing a SIGABRT error. So once I enable that from my app's build summary page (Or add it to the info.plist file as a supported orientation) it works fine. But then anytime in my game if you turn the iPhone it will flip to portrait mode if it senses you turned it that way. I've tried messing with the shouldAutorotateToInterfaceOrientation method from my AppDelegate.m and it's not getting called AT ALL, not at any time is it being called. I threw an NSLog statement in the method to be sure if it's being called, and it's not.
So, basically my real issue is. I need my game to STAY in landscape mode BESIDES when the Game Center login screen pops up. How do I do this in a Cocos2d 2.0 game?
I'm am using iOS6

First, make sure that the app supports portrait and landscape orientations in the target summary.
Then you'll need to make a new root view controller that forces you into landscape mode so that your game doesn't start rotating strangely:
#implementation CUSTOM_RootViewController
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate {
return YES;
}
#end
Finally, in the AppDelegate.m file, replace the original navigation controller with your new one:
// Create a Navigation Controller with the Director
//navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
navController_ = [[SMD_RootViewController alloc] initWithRootViewController:director_];
navController_.navigationBarHidden = YES;
Now you should be able to overlay a portrait view on top.
Hope this helps!

Use this code in AppDelegate.mm
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
{
return UIInterfaceOrientationMaskLandscape;
}
#else
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
#endif

In IOs6 shouldAutorotateToInterfaceOrientation method not worked, so u change in appDelegate .m file [window addSubview:viewcontroller] to [window setRootviewcontroller:viewcontroller] after its works fine.

Related

show specific viewcontroller only in landscape, but support iPad multitasking features

I´m developing an application for iPad & iPhone.
The App is supporting on iPad all Orientations, because of Multitaskingfeatures.
On iPhone my App is supporting only Portrait.
For one Specific ViewController I want on both devices to support only Landscape.
On the iPhone was using following solution:
I disabled all orientations in .plist and worked with two Navigationcontroller.
One for landscape and one for Portrait.
pushing my VC for Landscape:
LandscapeNavigationController *navController = [[LandscapeNavigationController alloc] init];
[UIApplication sharedApplication].keyWindow.rootViewController = navController;
[navController pushViewController:[Logic sharedInstance].myLandscapeViewController animated:YES];
Code in my NavigationController:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate {
return YES;
}
My Problem is that I cant handle the orientation on iPad in code because I have to enable all Orientations in .plist to support Multitasking.
So the delegatemethods supportedInterfaceOrientations in my Navigationcontroller wont be called.
Has anybody an idea to support multitasking on iPad AND allow one specific ViewController only one supportetInterfaceOrientation?

IOS 6 Storyboard rotation doesn't work as expected

I'm developing an iOS6 App with storyboards and i'm encountering an unexpected beahviour.
My app is almost in portrait mode , and i would keep this orientation in all the views except two.For this reason the project supports both landscape and portrait mode, i've subclassed navigation controller with a category (as explained almost everywhere :-)in Appdelegate.m and every view controller implements
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait; (landscape where needed)
}
and
-(BOOL)shouldAutorotate{
return YES;
}
Everything seems to work well except the fact that in the transition between a landscape view to a portrait one (not vice versa ?) , all the elements of the ui are displayed in landscape(imagine that you're keeping the phone horizontal), if you turn the phone , the rotation event is fired, the ui turns back in portrait and only now is locked to this orientation.Is there a way to fire the rotation BEFORE the view is presented?
Why the shouldAutorotate is not called at the ViewWillAppear stage?
Thank you!
Remove both the above function and try this it should work
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
Return YES for supported orientations
}
if still it's not working then try this change the appDelegate
[window addSubview:nav.view];
to this code
window.rootViewController=nav;
I found this online chapter very good for explaining UIViewControllers and rotation.
http://www.apeth.com/iOSBook/ch19.html#Rotation
It s a big page, scroll down to Rotation.

Force Landscape iOS 6

I am looking to have one view in my app have landscape orientation. I have managed to get the view to stay in landscape when rotated manually, but if the device is already portrait, it stays portrait, regardless of its supported orientation (set using supportedInterfaceOrientations method) . Is there a way to get the view to rotate automatically? I have tried:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
but this doesn't work.
Any suggestions would be greatly appreciated!
One way to do this is by overriding preferredInterfaceOrientationForPresentation but in order for that to be called the viewController has to be presented (as in modal) and not pushed as mentioned here:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
NSLog(#" preferred called");
return UIInterfaceOrientationPortrait;
}
In order to present your viewController in a UINavigationController use:
UINavigationController *presentedNavController = [[UINavigationController alloc] initWithRootViewController:protraitViewController];
[self presentViewController:presentedNavController animated:YES completion:nil];
To make UINavigationController respect your current viewController's orientation preferences use this simple category instead of sub-classing.
Also, this part of Apple's documentation is a good read for understanding iOS orientation handling better.
Define the following in the UIViewController for your landscape-only view:
- (UIInterfaceOrientation) supportedInterfaceOrientations
{ return UIInterfaceOrientationLandscapeLeft; } // or right or both
This should prevent your view from ever appearing in portrait. From iOS documentation:
Declaring a Preferred Presentation Orientation
When a view controller
is presented full-screen to show its content, sometimes the content
appears best when viewed in a particular orientation in mind. If the
content can only be displayed in that orientation, then you simply
return that as the only orientation from your
supportedInterfaceOrientations method.

UINavigationController Force Rotate

My application is primarily portrait, however there is one view that REQUIRES a landscape orientation.
My views are contained within a UINavigationController, which (apparently) is the cause of this issue.
All UIViewControllers except one have this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
The UIViewController that requires Landscape has this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Now, what happens is when the user reaches the landscape UIViewController, it is shown in portrait. The user can then rotate their phone and it displays in landscape as I want it to (locking to landscape). The user then progresses onwards to a portrait UIViewController and the same happens: it start in landscape, then they rotate their phone and it becomes portrait again (and locks to portrait).
It seems orientation locking is allowed between UIViewControllers, however auto-rotation / programmatically changing the orientation is somehow blocked.
How do I force the phone to update to the correct orientation?
There is a temporary solution: I can detect the orientation of the device and show a message asking them to rotate the device if it is not correct, however this is not optimal.
I had the same requirement for one of my applications!!!
luckily I found a solution!
In order to keep main viewcontroller landscape, no matter from what orientation it was popped/pushed, I did the following thing: (in viewWillAppear:)
//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
P.S.Tested on sdk 3.2.5 ios 5.0.1.
P.S. On iOS 8 previous answer results some screen flickering and also - it is not stable (In some cases It does not work for me anymore.) So, for my needs, I changed the code to: (ARC)
//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];
[self.navigationController presentViewController:[UIViewController new] animated:NO completion:^{
dispatch_after(0, dispatch_get_main_queue(), ^{
[self.navigationController dismissViewControllerAnimated:NO completion:nil];
});
}];
//I added this code in viewDidDissapear on viewController class, which will be popped back.
Hopefully it will help!
This might help. You can call the following method upon appearing, where appropriate. e.g. in -viewWillAppear:animated
attemptRotationToDeviceOrientation
Attempts to rotate all windows to the orientation of the device.
+ (void)attemptRotationToDeviceOrientation
Discussion
Some view controllers may want to use app-specific conditions to
determine the return value of their implementation of the
shouldAutorotateToInterfaceOrientation: method. If your view
controller does this, when those conditions change, your app should
call this class method. The system immediately attempts to rotate to
the new orientation. A rotation occurs so long as each relevant view
controller returns YES in its implementation of the
shouldAutorotateToInterfaceOrientation: method.
Availability
Available in iOS 5.0 and later.
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html
Use this,
[[UIDevice currentDevice]performSelector:#selector(setOrientation:) withObject:(__bridge id)((void *)UIInterfaceOrientationLandscapeRight)];

MPMoviePlayerViewController not playing in Landscape orientation under 5.1

Has anything changed in 5.1 which would affect how a MPMoviePlayerViewController works regarding device orientation?
I started getting reports from users today that videos were playing only in portrait mode. I figured out that they were using 5.1 and I quickly upgraded a device to recreate the situation. My code has not changed and works perfectly in 4.x, 5.0, and 5.01.
All the views in my app display in portrait mode except when a user clicks on a video, the movie player is suppose to take over the whole screen and launch into landscape more. The app using the 5.0 SDK but targeting 4.0. Here is the code I am using to display a video:
VideoPlayer *vp = [[VideoPlayer alloc] initWithContentURL:movieURL];
vp.moviePlayer.movieSourceType = src;
vp.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
vp.moviePlayer.shouldAutoplay = TRUE;
[self presentMoviePlayerViewControllerAnimated:vp];
VideoPlayer is a subclass of MPMoviePlayerViewController where the shouldAutorotateToInterfaceOrientation is overridden like so:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIDeviceOrientationLandscapeLeft);
}
This pattern is recommended all over the internet and even by Apple. I don't understand why its not working under iOS 5.1 or why more people aren't complaining about this.
Any help will be greatly appreciated.
I had the same problem also - i was playing the movie on a opengl subview, (im making an interactive ebook in landscape mode so needed my movie - (in a uiview) to play in landscape also)
I corrected this by:
subclassing the open glview to a *viewcontroller then linking that *viewcontroller to the window
So while working with cocos2d i can now use all uikit in the correct orientation.
Sending all uikit views to my subclasses opengl view. (while making sure to add in my app delegate and checking that orientation is stated in plist too.)
"#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
"#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
"#endif
hope this helps someone :) im very new at cocos2d so it took a while to figure out what i was doing wrong.
I had the same issue in iOS 5. The only way I was able to get it to work was to subclass MPMoviePlayerViewController.
#implementation MovieViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
} else {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
#end
It looks you have already tried to do this, but this block of code is working for me on the device with iOS 5.1. Not sure about the simulator.
I had a bunch of orientation issues after upgrading to iOS 5.1. For me, it was because the allowed orientations of sibling viewcontrollers up the chain resulted in no allowable orientation for a modal controller I was adding.
Do you have any cases in your view hierarchy where two subviews are added to a view? I was adding two subviews to my window in applicationDidFinishLaunching, and before iOS 5.1, they could have independent allowable orientations. ie, I could have one fixed in portrait orientation while the one on top rotated. Now, the other subview insists on portrait orientation.
My solution was to force the non-rotating view below:
[self.window insertSubview:self.nonRotatingViewController.view belowSubview:self.rotatingViewController.view];
This post helped me figure that out (and has some code):
iOS: Disable Autorotation for a Subview