i stuck on a problem that drives me crazy!
I have an iPad application starting with a TabBarViewController. Every Tab has it's own ViewController and nib-file.
To make interface orientation possible I added all orientations to my info.plist and subclassing my TabBarController to set:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Every View is autoresized and formatted well for displaying the right Orientation if I rotate the Interface. If I test it in the simulator, everything looks fine and I can rotate between the Orientations.
Now the point that drives me crazy:
If I launch the App in Portrait Mode, all works fine.. but if I launch in Landscape, I get an error and my Interface orientation seems still to be Portrait, while the Simulator is in Landscape Mode!!
The Error:
2011-05-24 21:50:15.011 Project[57995:207] Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.
I checked for Orientation like this:
-(void)viewWillAppear:(BOOL)animated{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight)) {
NSLog(#"Orientation: Landscape");
}
else{
NSLog(#"Orientation: Portrait");
}
}
The Log says it is in "Landscape" Mode if I launch in Landscape, but if I change tab to another it looks terrible because the View is displayed in Portrait mode instead.
On change back to the start-view where i asked for Orientation… the log displays "Portrait"… but the Simulator is still Landscape!
I can't figure out why the Orientation is Portrait on start,…
even if I start in Landscape…
Any idea how to solve this problem?
Ok. So the documentation says viewWillAppear: is called prior to all animations. And when your app starts, its initial orientation is Portrait. Based on what your orientation is, it then rotates to that orientation. Since it animates to the orientation off screen, this must be called after viewWillAppear:/ So when viewWillAppear: is called, its still in Portrait. I tested this myself.
I solved the problem!
Simply used this in viewWillAppear method of all my Views, to make it work when started in Landscape mode:
if(([[UIApplication sharedApplication]statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) || ([[UIApplication sharedApplication]statusBarOrientation] == UIInterfaceOrientationLandscapeRight)){
//Landscape View
}
else{
//Portrait View
}
Works fine for me!
Related
I have a view controller with an UIButton. That view controller is shown in landscape right mode only. Until iOS 8.0.2, all works fine. I'm testing with an iPhone 5S.
But after installing iOS 8.1.1, the following happens:
If I click the button just right after the view controller is shown, all works fine. The touch up inside event is received.
But if I start to rotate the phone a few times, even when the view does not change orientation (remember, landscape right only), the events are not received anymore.
Here is the relevant code:
-(BOOL)shouldAutorotate
{
NSLog(#"shouldAutorotate");
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSLog(#"supportedInterfaceOrientations");
return UIInterfaceOrientationMaskLandscapeRight;
}
I should mention that the method shouldAutorotate is called several times.
Thank you in advance. Any help would be appreciated.
If you use only one landscape right mode, try to detect device orientation like here:
Detecting iOS UIDevice orientation
I want my app to support landscape only (left and right) on iPhone and iPad.
Hence in the info.plist I added landscape as the supported orientations.
My root controller is a UINavigationController with one controller on its stack.
However, my controller also rotates to portrait but not to portrait upside down.
If I Add GetSupportedInterfaceOrientations() (supportedInterfaceOrientationsForWindow: in ObjC) to the app delegate and return landscape there, the rotation completely stops working.
How hard can it be?
Did you try to use?
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
hope this helps..
Figured it out. The topmost view controller has to return the interface orientations it wants to rotate to. In my case, that's the UINavigationController.
And the change was already in iOS6.
So, I'm in a bit of a bind... According to this post, the orientation of the iPhone/iPad is portrait up to a point after which the "auto-rotate" function inside the controller tells iOS that the orientation has changed. My problem is that it appears as though the tableview cells are loading before I have a chance to detect a change in the orientation. My tableview depends on the orientation of the device, so I can't load it until the orientation is known. Is there something I don't know?
Thanks guys!
I believe you are providing support for both the LAndScape and Potrait mode for the application so you should detect the device orientation in the cellForRowAtIndexPath method and create the cell for the current orientation:
if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight) {
Identifier= #"aCell_portrait"
}else Identifier= #"DocumentOptionIdentifier_Landscape";
When the auto-rotate function is called, you could just run
[tableView reloadData];
to reload the table after rotation has occurred.
Ok I have an interesting issue on an iPad application I am developing.
When the app launches in portrait mode the layout works as expected. I rotate the iPad and the rotation works fine.
When the application launches in landscape mode there is additional white space appearing and the layout does not work as expected. But when I rotate the application to portrait it rotates just fine. It also lays out fine when I rotate it back to landscape.
What could be causing this problem? The view controller in question is a view controller that contains a UINavigationController (I had to add in a header). I wonder if it is something with UINavigationController.
Your view is expecting Portrait mode upon launch. In your view Controller, you need to let it know to look for orientation, and load the corresponding view.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight))){
self.view = landscape;
}else if(((interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))){
self.view = portrait;
}
return YES;
}
Ok so what was strange in my application is that the layout would become correct when the tab controller switched tabs back to the view that was being funky. So, I added a hack in order to switch between the tabs before the makeKeyAndVisible of the main window.
I did try your suggestion WrightsCS. The real reason it didn't work is because I'm loading UINavigationController's view in the sub view of the page, so I didn't really have control of the layout that was messing up. The top bar of the navigation controller was loading a little lower than it should have been.
i have got 2 GUIs and 2 Controllers
1 is called landscapeguicontroller and the second is called highguicontroller.
Now generally i call the highguicontroller, and when i rotate my iphone it detects that and then it shows the landscapeguicontroller:
Code:
landscapeguicontroller *neu =[[landscapeguicontroller alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:neu animated:YES];
[self dismissModalViewControllerAnimated:YES];
The Problem is that then the animation pushes the new window from the beyond side of the iphone up into the window.
In the Landscapeguicontroller,i have added to the the following lines:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
when i want go back to the highguicontroller i call:
[self dismissModalViewControllerAnimated:YES];
that all works , but just in the second animation i see the correct "rotation animation".
Have you got any suggestions?
So a short Problem description:
in the 1. animation from high to landscape, the landscape is pushed into the window
BUT in the 2. animation from landscape to high, the rotation looks like a real rotation...
i want the 1.animation look like the 2. animation
best regards
Ploetzeneder
To avoid "The Problem is that then the animation pushes the new window from the beyond side of the iphone up into the window.", try setting the view controller's modalTransitionStyle property to one of the following, whatever you prefer:
typedef enum {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
} UIModalTransitionStyle;
Also, if you want to avoid the animated rotation, you can set your shouldRotate... method to disallow other orientations, but then set up to receive notifications when the device physically changes orientations, and present your modal viewcontroller when in the appropriate orientation for it. See Apple's "AlternateViews" sample code for an example of this.
The notifications reflect the physical orientation of the device, and you can receive them whether the interface is allowed to change or not. (You can look at the UIApplications's statusBarOrientation property to see what orientation the UI is in).
It sounds like you want the sequence to go like this:
Physically rotate the device from portrait to landscape
Animate the portrait view (highguicontroller) to landscape
Push the landscape view (landscapeguicontroller) up from the new "bottom" of the screen
If that's right, you'll need to have something like the following in your highguicontroller implementation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}
This will take care of step 2 (it will rotate the portrait view to landscape in either direction).
Then you'll want something like this:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if(fromInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self presentModalViewController:landscapeguicontroller animated:YES];
}
else {
[self dismissModalViewControllerAnimated:YES];
}
}
That should present the landscape view after the rotation animation is complete and then dismiss it after the device is rotated back to portrait.
Hope that helps!