I am new to the cocos2d API and have noticed that there are a few ways to set the screens orientation within the templates. I have not been able to figure out the correct way to set my orientation to LandscapeRight and keep it that way throughout the entire game. How do I change my orientation so that it maintains LandscapeRight? Any help is appreciated. Thank you!
The answer here has changed with cocos2d 2.0, as CCDirector is now a ViewController on iOS:
CCDirector no longer supports device orientation. All autorotation and
device orientation is handled by RootViewController now. Fortunately,
[[UIDevice currentDevice] orientation] can be used in place of
[[CCDirector sharedDirector] deviceOrientation]. The enums are the
same, except that they begin with UI instead of CC.
Forcing a specific orientation is a simple matter of returning YES
only to the desired orientation in the RootViewController method
shouldAutorotateToInterfaceOrientation.
Choosing between Cocos2D v1.x & 2.x and Tips for updating to Cocos2D 2.0 at learn-cocos2d.com
Modify GameConfig.h from the cocos2d template.
#define GAME_AUTOROTATION kGameAutorotationNone
/* original code is kGameAutorotationUIViewController. */
And modify AppDelegate.m as well.
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
/* original code is "Left". */
#endif
Use this line:
[[CCDirector sharedDirector] setDeviceOrientation:kkCCDeviceOrientationLandscapeRight];
In the RootViewController.m,search for the line
return ( UIInterfaceOrientationIsPortrait(interfaceOrientation ));
change it to
return ( UIInterfaceOrientationIsLandscape(interfaceOrientation ));
if you added shouldAutorotateToInterfaceOrientation and not solved your problem
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
THEN
Try to add this line to appDelegate.m
[window_ setRootViewController:navController_];
Good Luck
The correct answer - took me a while to find - is in the info.plist, change the supported interface orientations values, item 0 and item 1 have 4 possible values, Portrait (top home button) etc.
Related
I am new to cocos2d game developing. Here, my game is developed in portrait mode. I just want to convert landscape mode. and tell me which method is used instead of shouldAutorotateToInterfaceOrientation method because this method is not available in iOS 6?
My whole game is developed portrait mode from the start.
Thank you in advance.
you will find below code in appdelegate.mm file
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
change it to.
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
let me know it is working or not!!!!
Not sure this will solve your problem, but as you mentioned How to handle orientation in OS6, I would like to give you the code what I am using for Handling Device Orientation in iOS 6 and iO5 etc.
So here is the code snip, where you can decide what orientation support you want in your app
Handle Screen Orientations in iOS 5 and iOS 6
//For up-to iOS 5.0
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported all orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
//For iOS 6.0
-(NSInteger)supportedInterfaceOrientations
{
//Supporting only portrait orientation.
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate
{
return NO;
}
Reference
Hope this will help you!!
Go to target and set supported interface orientation.
In the default cocos2d 1.0 beta template, AppDelegate.m has some code:
// AppDelegate.m
// IMPORTANT:
// By default, this template only supports Landscape orientations.
// Edit the RootViewController.m file to edit the supported orientations.
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation: kCCDeviceOrientationPortrait];
#else
[director setDeviceOrientation: kCCDeviceOrientationLandscapeLeft];
#endif
Next, In GameConfig.h, we have defined:
// GameConfig.h
#define kGameAutorotationNone 0
#define kGameAutorotationCCDirector 1
#define kGameAutorotationUIViewController 2
//
// Define here the type of autorotation that you want for your game
#define GAME_AUTOROTATION kGameAutorotationUIViewController
Together, this was working to produce a landscape setup that auto-rotated to either landscape-left or landscape-right depending on how you held the device. TableViews autorotated as well (I have several tables placed on top of some cocos2d CCScenes).
However...I updated to iOS6 last night. As well as XCode 4.5.
I'm hoping it's not just me, but my app's rotation is completely broken now. I'm trying to fix it via code for at least one tableview...changing GAME_AUTOROTATION seems to have no affect on tableviews, just the cocos2d CCScenes (which is half of the solution in a way).
I may just start from scratch and get something built up instead of working with pre-written code, this is just mega-frustrating!! Thanks a lot, Apple!
My partial solution is
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
//[director setDeviceOrientation:kCCDeviceOrientationPortrait];
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#endif
Do you have a better solution?
Thanks
The answer was to upgrade my stuff to cocos2d 2.0 and to remove the dependency on the RootViewController, which is no longer used.
navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
navController_.navigationBarHidden = YES;
[window_ setRootViewController:navController_];
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
I have a ebook reader app where in, i need to programmatically adjust the device orientation according to the layout of the page... i.e, The device should support all orientations for some pages and only landscape for some other pages. Is there anyway in which i can force a orientation change programatically
You can use the answer from jbat100 plus a call to setStatusBarOrientation:animated in UIApplication to achieve the effect.
Note that the behavior for this has changed as of iOS 6.0. For further info, see: Autorotate in iOS 6 has strange behaviour
The gist is that should/will/did/etc have been deprecated and have been replaced with a cleaner, more dynamic implementation. Which we should all be thankful for.
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
This can set the device orientation to LandscapeRight programmatically.
You cannot force the device orientation to some value, the system tells you the device's orientation, not the opposite. You can rotate your views using CGAffineTransform and such (a related post here).
Actually you can force any rotation. At least I was able to do it. Solution I used: https://stackoverflow.com/a/10146270/894671
This works for me on Xcode 6 & 5.
- (BOOL)shouldAutorotate {return YES;}
- (NSUInteger)supportedInterfaceOrientations {return (UIInterfaceOrientationMaskPortrait);}
In my iPad app, I need to run some layout code to set the proper layout depending on the orientation. By default, the layout is configured for the landscape orientation, so in the case that the app starts in portrait mode, I need to take extra action to configure the views properly for display in portrait.
In my -application:didFinishLaunchingWithOptions: method, I check the orientation using [[UIDevice currentDevice] orientation]. The problem here is that it always returns portrait even if the app is starting in landscape. Is there any way around this?
This is expected behavior. Quoth the UIViewController documentation:
Note: At launch time, applications should always set up their interface in a portrait orientation. After the application:didFinishLaunchingWithOptions: method returns, the application uses the view controller rotation mechanism described above to rotate the views to the appropriate orientation prior to showing the window.
In other words, as far as the device is concerned the orientation is portrait while the application is launching. At some point after application:didFinishLaunchingWithOptions: it will detect the different orientation and call your shouldAutorotateToInterfaceOrientation: method and then your other view rotation methods, which you should handle as normal.
This is the best way to check for orientation on launch. First, create a new method in your AppDelegate that checks the orientation:
-(void)checkLaunchOrientation:(id)sender{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
BOOL isLandscape = UIDeviceOrientationIsLandscape(self.viewController.interfaceOrientation);
if (UIInterfaceOrientationIsLandscape(orientation) || isLandscape) {
//do stuff here
}
}
At the end of -application:didFinishLaunchingWithOptions: run
[self performSelectorOnMainThread:#selector(checkLaunchOrientation:) withObject:nil waitUntilDone:NO];
Use self.interfaceOrientation in your view controller - it's a property of UIViewController that is set by iOS for you, and in some cases is more reliable than [[UIDevice currentDevice] orientation].
Here's a detailed description: http://bynomial.com/blog/?p=25
As mentioned in a blog post above, there is a set of macros for testing orientation. That blog post however mentions UIDeviceOrientationIsPortrait. I like the following below, it's a minor twist.
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
NSLog(#"Portrait");
}
else
{
NSLog(#"Landscape");
}
An observation I've made is that you can't call this code in a table view, pushed on to a Navigation Controller embedded in the split view controller. So in other words you can't call it from the master view controller. You have to replace the "self.interfaceOrientation" with splitviewcontroller.interfaceOrientation, assuming you maintain a reference to the parent split view controller.
Use the status bar orientation instead to detect it.
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
then perform the if's on the "orientation" you have obtained from above.
So the question is about checking orientation at startup. The answer is sadly "You can't".
But AFTER startup, you can check orientation the normal way (as others have described).
If anyone else comes here looking for an answer, simply stop looking since, at startup the orientation variable is not set (all views frames/bounds also report being in portrait even if they aren't).
You want to make sure you set the proper keys in your Info.plist to allow for the orientations you want:
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
Not that you need another answer, but I thought I should add that you almost never want to use [[UIDevice currentDevice] orientation]. That method returns the orientation of the device, which isn't necessarily the same as the orientation of the interface.
It's not true that you can't figure out the launch orientation, it is true that it's a pain in the rear to do so.
here's what you need to do.
your first UIViewController needs to have some special logic to nab the information you'd like.
you might even want to create a UIStartupController just for these purposes if it's that important to your flow.
in the case of my project, we already had such a startup controller present.
all you need is the following code
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.launchOrientation = UIDeviceOrientationUnknown;
}
return self;
}
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (self.launchOrientation == UIDeviceOrientationUnknown && duration > 0)
self.launchOrientation = UIInterfaceOrientationPortrait;
else
self.launchOrientation = toInterfaceOrientation;
}
basically, if we're not launching in UIInterfaceOrientationPortrait, the first rotation callback sequence will actually reveal the launch orientation.
if launched in UIInterfaceOrientationPortrait, then we need to check that the first rotation's duration is non zero, and then we know that it was launched from portrait.