I have a timer set up, in place, and working fully. My problem is that I do not know if it is possible to completely flip everything on screen and keep it in the same position after a certain amount of time has elapsed.
E.G.
I have a tree. After 30 seconds has passed flip the orientation from "landscapeleft" to "landscapeRight" and flip all sprites/timers on screen.
Is it possible?
Should I just change the orientation, check to see if the orientation has changed and if it has, change the sprites rotation?
Also, I would really like to Thank EVERYONE on this site for all of there help and putting up with my "easily answered" questions.
Thank You!
you could use a scheduling method like nash suggested along with a CCDirector orientation method [[CCDirector sharedDirector] setDeviceOrientation:kCCDeviceOrientationPortrait]; or whichever orientation you need.
-(void) flipOrientation:(ccTime)delta {
CCDirector *director = [CCDirector sharedDirector];
if ([director deviceOrientation] == kCCDeviceOrientationLandscapeLeft )
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
}
then when you schedule your method
[self schedule:#selector(flipOrientation:) interval:30.0];
this should do what you are asking for however i strongly suggest, as nash said, that you rotate instead of setting the orientation. You can rotate your main layer, or gameScene.. it will be more responsive and you can have control over how it animates. You can do it the same way as above by scheduling but instead of setting device Orientation just rotate your layer.... hope this helps
Related
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.
I have a small view on top of an mpmovieplayercontroller. When it is not fullscreen, I am able to adjust the frame of the view to the orientation (when the device rotates). But when I enter fullscreen mode, alothough I manage to present the view, I'm no longer able to maintain the correct frame when the device rotates. It looks like in fullscreen mode, the system simply using CGAffineTransformRotate on the status bar and the moviePlayer. How can I apply this CGAffineTransformRotate to rotate my view correctly?
EDIT:
Ok, so I updated the code to rotate 90% in the X axis after a change in orientation of the mpmovieplayercontroller but the view simply disappears after the first rotate. Here is my code:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
float angle = M_PI / 2; //rotate 180°, or 1 π radians
theView.layer.transform = CATransform3DMakeRotation(angle, 1.0, 0.0, 0.0);
[self changePositionBasedOnOrientation:toInterfaceOrientation]; //here we change the frame of the view
}
I'm not sure if this would necessarily be the correct way to do it (I guess you're adding a subview to the MPMoviePlayerController view?), but what you seem to be after is a callback to when the movie player rotates in fullscreen so you can adjust your own custom views.
You could register for rotation notifications on your custom view, which can then adjust itself every time it receives a callback. You register for rotation notifications as follows:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(layoutViewForOrientation:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
You should remember to endGeneratingDeviceOrientationNotifications and remove your notification observer when you're done with the fullscreen mode.
Ok,
So the best way to overlay the mpmovieplayercontroller in fullscreen is to it like that:
[[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] addSubview:mySubview]
It's a bit hacky, but legitimate. It gives you an easy way to deal with rotations (instead of using transformations).
Hi I have an app and I have two *.pngs for default splash screen:
Default-Landscape.png
Default-Portrait.png
What I want is to animate this default splash screen away when my app is loaded and ready to go.
To achieve this I would normally present an UIImageView with either default-landscape or default-portrait (depending on the device orientation), keep it on screen for a certain time and then animate it away.
My problem is that if I call [[UIDevice currentDevice] orientation] in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
The answer is always that the device is in portrait orientation even if I clearly have it in landscape. I tried this in simulator and on the device as well and the behaviour is the same.
Does anyone know a fix for this or maybe some other approach?
Thanks!
I had troubles with this and I solved it by making one image 1024x1024 and setting the contentMode of the UIImageView to UIViewContentModeTop, then using left and right margin autoresizing. So long as your portrait and landscape default images are the same layout then this will work fine.
Just to clarify here's what I used:
bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:SplashImage]];
bgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
bgView.contentMode = UIViewContentModeTop;
To get around this problem I installed the splash image view inside of a view controller that allowed both orientations. Even though the device reported the wrong orientation at startup, the view controller seems to get the right one.
You can use UIApplication statusBarOrientation as follows:
if ( UIDeviceOrientationIsLandscape( [[UIApplication sharedApplication] statusBarOrientation] ))
{
// landscape code
}
else
{
// portrait code
}
Maybe you could show a blank view with black background at start time and place [[UIDevice currentDevice] orientation] into this view's viewDidAppear and start your splash screen from there?
Another solution would be to read the accelerometer data and determine the orientation yourself.
To know at start what is the orientation (UIDevice orientation don't work until user have rotate the device) intercept shouldAutorotateToInterfaceOrientation of your View Controller, it is called at start, and you know your device orientation.
There are certainly times when you want to transition from the loading image to something else before the user gets control of your app. Unless your app is really simple, going from loading image to landing page probably won't be sufficient without making the app experience really suck. If you ever develop a large app, you'll definitely want to do that to show progress during setup, loading xibs, etc. If an app takes several seconds to prepare with no feedback, users will hate it. IMO, there's nothing wrong with a nice transition effect either. Almost nobody uses loading screens the way Apple suggests to. I don't know which apps you looked at that showed the "empty UI" type loading screens they suggest. Heck, even Apple doesn't do that except in their sample code and none of my clients would find that acceptable. It's a lame design.
Only the first view added to the window is rotated by the OS. So if you want your splash screen to automatically rotate AND your main view is rotatable then just add it as a child of that view.
Here is my code for fading out the appropriate splash screen image:
// Determine which launch image file
NSString * launchImageName = #"Default.png";
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
launchImageName = #"Default-Portrait.png";
} else {
launchImageName = #"Default-Landscape.png";
}
}
// Create a fade out effect
UIImageView* whiteoutView = [[[UIImageView alloc] initWithFrame:self.window.frame] autorelease];
whiteoutView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
whiteoutView.autoresizesSubviews = YES;
whiteoutView.image = [UIImage imageNamed:launchImageName];
[[[self.window subviews] objectAtIndex:0] addSubview:whiteoutView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
whiteoutView.alpha = 0.0;
[UIView commitAnimations];
Note: You'll have to update it to support hi-res screens.
It sounds like you're not using the launch image the way Apple recommends in the iOS HIG. It specifically calls out that you should not use it as a splash screen, but rather as a skeleton version of your actual UI. The net effect is that your app appears to be ready just that much faster.
The suggestions that you could draw a splash screen yourself after the app has launching in viewDidAppear or similar also are missing the basic purpose of a launch image. It's not a splash screen. If your app is ready, let the user interact with it, don't waste their time drawing a splash screen.
From my five minute survey of Apple apps and third-party apps, everyone showed a portrait launch image, loaded the portrait version of the UI, and then rotated to landscape. It's been a while since programming on iOS, but I think this mirrors the order of the method calls -- first your app gets launched, then it is told to rotate to a particular orientation.
It might be a nice enhancement request to file with Apple though :)
I am developing an iPad application which is basically a big drawing canvas with a couple of button at the side. (Doesn't sound very original, does it? :P)
No matter how the user holds the device, the canvas should remain in place and should not be rotated. The simplest way to achieve this would be to support just one orientation.
However, I would like the images on the buttons to rotate (like in the iPhone camera app) when the device is rotated. UIPopoverControllers should also use the users current orientation (and not appear sideways).
What is the best way to achieve this?
(I figured I could rotate the canvas back into place with an affineTransform, but I don't think it is ideal.)
Thanks in advance!
Just spouting off an idea (not sure if it would work or not)...
Perhaps you could have your screen controlled by a UIViewController that supports all orientations, but have the canvas be controlled by one that only supports a single orientation (ie, returns NO in its shouldAutorotate... method).
If that doesn't work, I'd probably just go with the affineTransform route.
I discovered a way to do this, similar to what Dave DeLong proposed.
Using a transform worked, but it wasn't ideal. Although the end result (end of the animation) was what I wanted, it would stay show some kind of shaky rotation animation.
Then I found this:
https://developer.apple.com/iphone/library/qa/qa2010/qa1688.html
Which says that a second (or third etc.) UIViewController added to the WINDOW would not receive rotation events, and therefore would never rotate. And that worked!
I created a 'fake' UIViewController with a blank view and added that as the first view controller. This receives the rotation events which I then pass on to the other view controllers that can then choose whether to rotate - the entire view or just button labels.
It is a bit hacky... But I guess the user won't notice.
Using the willRotateToInterfaceOrientation method, you should be able to use some simple logic to swap out the images:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
//The following if statement determines if it is an iPad, if it is then the interface orientation is allowed. This line can be taken out to support both iPhones an iPads.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
//Swap images and use animations to make the swap look "smooth"
//NSLog(#"Landscape Right");
} else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
//Swap images and use animations to make the swap look "smooth"
//NSLog(#"Landscape Left");
} else {
//Swap images and use animations to make the swap look "smooth"
//NSLog(#"Portrait");
}
} else {
}
}
To change an image in your interface programmatically:
[myUIImageView setImage:[UIImage imageNamed:#"myImage.png"]];
Also, to make sure the view doesn't auto-rotate use the shouldAutorotateToInterfaceOrientation method to tell your app to stay in portrait.
1) Is it possible to change the speed of autorotation on the iPhone?
2) Is it possible to time an animation to take place during the autorotation animation? I would like to resize a photo while rotation is occuring, rather than when it's done.
1) not that I know of
2) Yes, see this method:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW53
As for the first question, I haven't used this but check it out:
[UIApplication sharedApplication].statusBarOrientationAnimationDuration = [NSTimeInterval ...];
See docs for UIApplication. The problem is that I don't know that this actually rotates the rest of your views. You may, however, be able to rotate the window's coordinate system around "manually" using UIWindow and [UIView beginAnimations ...] in order to recreate the whole effect.
Please post sample code somewhere if you get it working!