Prevent users to see some views in landscape - iphone

I've had to allow landscape orientation in all my views because one of them needs to handle landscape orientation and my app is a tabbar based iphone app. Now some views are obviously showing ugly when device is in landscape mode. I'm thinking of subclassing UIView and use the subclass to show a "warning" screen when user is not in a portrait mode in some views. Any idea on what could be of best practices about it ?
Thx for helping,
Stephane

There is a willRotateToInterfaceOrientation:toInterfaceOrientation method in the UIViewController class. iOS calls it when an end user rotates phone. You may override it to display and hide a warning message.
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (! UIDeviceOrientationIsPortrait (toInterfaceOrientation))
[self displayWarningMessage];
else
[self hideWarningMessage];
}

Related

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.

How to get InterfaceOrientation from iPhone (not DeviceOrientation)?

I've created a modalviewcontroller and all the subviews are created by code. When I'm testing the app, I find a problem. Then main cause of the problem is that an app shouldn't support UpsideDown orientation, but devices may happen to be in that orientation.
If I:
Rotate the device to Portrait orientation, and then to UpsideDown mode and presentModalView, the subviews in modalviewcontroller should appear the same as Portrait orientation.
Rotate the device to Landscape orientation, and then to UpsideDown mode and presentModalView, the subviews should be treated differently.
The above situation tells me that I should create subviews in modalviewcontroller according to previous InterfaceOrientation.
The problem is: How to get the previous screen's InterfaceOrientation? Getting the device orientation won't do any help in this situation.
PS: I'm writing a lib, I may give my users the interface to send me the "toInterfaceOrientation" from -willRotateToInterfaceOrientation:duration: but are there any ideas about how to get the orientation in my code?
In any UIViewController you can access the property interfaceOrientation like this:
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
// do stuff
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}

how do I play fullscreen landscape movie on iOS4 in a portrait application?

The problem is the following:
I have an application in which all viewcontrollers are portrait only 9typical tabbar/navigation app), but I would like to play a move in fullscreen landscape mode. This seems impossible in iOS4 ...
The best I could come up with was to add the mpmoviecontroller view to my parent view and rotate it by hand, but then there are 2 issues, the first being that i dont have the "Done" button, and that the user still has the possibility to press the "fullscreen" button making the view go portrait and completely wrong.
When using the [moviePlayer setFullscreen:YES animated:YES]; method it automatically sets the view in portrait and there is no way of rotating it.
any suggestions?
I don't remember where I found this, but you can subclass MPMoviePlayerViewController so its only support landscape orientations:
#interface CustomMPMovie : MPMoviePlayerViewController
#end
#implementation CustomMPMovie
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
#end
Hope it helps..
For full screen playback use MPMoviePlayerViewController and then to make it launch and play in landscape format use the "shouldAutorotateToInterfaceOrientation" method on the MPMoviePlayerViewController class.
It looks like this:
[yourInstanceOfMPMoviePlayerViewController shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationLandscapeRight];

Landscape only iPhone app with multiple nibs

I'm developing an iPhone application that has several nibs, and should be landscape only.
The application is set to start in landscape mode via its Info.plist file.
I have two view controllers:
FirstViewController and SecondViewController.
For each of these I have a nib file, where the view is in landscape. Both view controllers are added to my MainView nib as outlets, and their views are lazily initialized.
When the application loads, the first view displays in landscape, as expected. However, when I switch to the second view, the device (or simulator) remains in landscape, but the view is rotated, as if the device were in portrait mode, braking my interface.
In both UIViewController classes I have the following code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}
and to switch views, in my app delegate I'm doing:
[viewController.view removeFromSuperview];
[window addSubview:secondViewController.view];
where viewController and secondViewController are the two outlets where the view controllers are connected.
This is how the second view looks in IB:
alt text http://img27.imageshack.us/img27/4898/picture1ni.png
and this is how it looks in the simulator:
alt text http://img402.imageshack.us/img402/4866/picture2wt.png
Why is that the second view is displaying in landscape but with the interface rotated?
I wouldn't like to deal with transform properties, since that seems overkill.
I starred this question hoping someone would give you an insightful response and I'd learn something.. sadly I'm afraid that you might need to use transforms to get this to work properly. Here's the code I've been using lately to solve the problem:
- (void)forceLandscapeForView:(UIView *)theView {
theView.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
theView.bounds = CGRectMake(0, 0, 480, 320);
theView.center = CGPointMake(160, 240);
[theView setNeedsLayout];
[theView setNeedsDisplay];
}
Then when you're adding your new view, check the current orientation and if necessary force the rotation:
if (!UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
[self forceLandscapeForView:_activeViewController.view];
}
Then of course you'll want to respond appropriately to shouldAutorotateToInterfaceOrientation in each of your view controllers:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
I would love to hear about alternate solutions if this isn't all necessary. There is also one caveat I've noticed with this setup: if you have a transition between views, and you rotate the phone during that transition, it's possible for the views orientations to get flipped or "stuck" on the wrong landscape orientation, such that you need to turn the phone over (landscape-right vs landscape-left) as you navigate between views.
it is just a suggestion but you can try to return NO in the shouldAotorotate method for the second view. Or try to make it in the portrait view in the IB. It seems that your view was loaded correctly(in the landscape mode) but then received shouldAutorotate message and had been rotated by 90 degrees.