I am creating an App in portrait and Landscape Mode for iPad . I create a XIB in Landscape Mode for iPad but when i run that App it always shows in portrait Mode .
I set all setting under property list(.plist) file as "Supported Interface orientation(iPad)" and set Landscape(Left Home button) and landscape(Right Home Button) and also check the Orientation from the Code but all this doesn't work.
please help us if any one knows the exact problem or this , we are using Navigation Controller
Add this line of code in didFinishLaunchingWithOptions in delegate.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(preferredInterfaceOrientationForPresentation) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
Then add following methods in delegate first and run the app, if fixed, COOOOL else add following four methods in each your view controller. You problem will be fixed.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
Related
I've tried the following methods to force landscape on one of my views:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
- (BOOL)shouldAutorotate{
return YES;
}
Neither did work. Note that I'm testing on the simulator and on an iPhone
Thanks
please goto Targets in Xcode and in Generate Category select Device Orientation ticked for Landscape Orientation.
In my project I have allowed only portrait rotation, but for one ViewController I would like to enable also landscape. I'm presenting this ViewController as ModalViewController, I've tried using methods - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation or iOS 6 methods like -(NSUInteger) supportedInterfaceOrientations but nothing actually worked. The view didn't rotate although those methods got called.
After this I've tried to rotate it by myslef with listening to those notifications :
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
but even though I was able to manually rotate the view in method didRotate: it's very messy and I can't rotate the StatusBar.
I would really like to use standard methods like shouldAutorotateToInterfaceOrientation, but I don't know how. Anyone?
Add this in your app delegate.m
# pragma mark - Rotation
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([self.window.rootViewController isKindOfClass:[MVYSideMenuController class]]) {
// Get topmost/visible view controller
UIViewController *currentViewController = [self.window.rootViewController.childViewControllers lastObject];
// Check whether it implements a dummy methods called canRotate
if ([currentViewController respondsToSelector:#selector(canRotate)]) {
// Unlock landscape view orientations for this view controller
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
// Only allow portrait (standard behaviour)
return UIInterfaceOrientationMaskPortrait;
}
-(void)canRotate
{
}
and then add this method
-(void)canRotate
{
// just define the method, no code required here
}
in every ViewController (.m files) where you want to provide rotation. You can also include here -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation method to react when the device rotates:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
switch (orientation) {
case 1:
case 2:
//NSLog(#"portrait");
break;
case 3:
case 4:
//NSLog(#"landscape");
break;
default:
//NSLog(#"other");
break;
}
}
Subclass a navigation controller for your screen that requires rotation.
In the .m
// Older versions of iOS (deprecated) if supporting iOS < 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
// iOS6
- (BOOL)shouldAutorotate {
return YES;
}
// iOS6
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
This overrides the rotation methods set in the summary page for iOS 6.
In iOS 6 the view controllers only look to there parent or root controller for rotation methods
can't you just call the shouldAutoRotateToInterfaceOrientation in the viewDidLoad and viewWillAppear like so:
[self shouldAutorotateToInterfaceOrientation];
that should call the method if its in your ViewController
Implement is in all controller and Return on that interfaceOrientation which you need for a specific controller
For All
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation{
return YES;
}
For Landscape
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
For Portrait
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
}
All view controllers in my app are working only in portrait orientation except one which can be portrait or landscape oriented.
I have some usage scenario like following:
I push controller which works in both orientations to UITabBarController
User change orientation from portait to landscape
User press "back button"
After these actions application remains in landscape orientation and does not change it automatically to portrait.
I control view controller orientation using supportedInterfaceOrientations (I use iOS 6.0). What I do wrong? How can I get correct behaviour when application automatically change orientation to allowed when user press back button? Thank you for answer!
In iOS 6 (and possibly earlier), if a view controller is offscreen when the device rotates, it does not get any notification. Nor does it get sent willAnimateRotationToInterfaceOrientation:duration: when it becomes the top view controller.
You need to keep track of the current orientation of the view controller and check the device orientation in viewWillAppear:. If they are different, you can use willAnimateRotationToInterfaceOrientation:duration: to set it correctly.
Since this is something you are likely to do a lot, you may want to create a generic superclass that your view controllers inherit from.
A typical solutions is:
#implementation MyHandlesOffscreenRotationController
{
BOOL isShowingPortrait;
}
- (void) viewDidLoad
{
[super viewDidLoad];
isShowingPortrait = UIInterfaceOrientationIsPortrait(
[[UIApplication sharedApplication] statusBarOrientation]);
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
BOOL currIsPortrait = UIInterfaceOrientationIsPortrait(
[[UIApplication sharedApplication] statusBarOrientation]);
if ((isShowingPortrait && !currIsPortrait) ||
(!isShowingPortrait && currIsPortrait)) {
[self willAnimateRotationToInterfaceOrientation:
[[UIApplication sharedApplication] statusBarOrientation]
duration:0.0f];
}
}
#end
Just override -(BOOL)shouldAutoRotate and - (NSUInteger)supportedInterfaceOrientations inside a UINavigationController category, then ViewController will force rotate to its supported orientation after pop from other ViewController.
#implementation UINavigationController (Rotate)
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
#end
iOS 9 and above
At the time of pop just write the below-mentioned code in your viewWillAppear method.
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]forKey:#"orientation"];
With this, your view will appear in portrait mode.
P.L. has a nice solution in this topic: Present and instantly dismiss an empty modal view controller which allows only portrait | landscape
How to change the device orientation programmatically in iOS 6
I'm in a real mess right now . I used apples sample code which does this :
Create a portrait view controller and a landscape view controller
Potrait event controller then registers for device orientation changed notifications
When device is rotated it presents a modal view controller for the landscape view or dismisses the landscape view if it is rotated back to portrait .
Everythings working as it should except for a little problem ....
Now to my problem . I used this to launch a rotatable view controller from a table view . It can be rotated and works fine . But if I initially launch it in landscape mode it will still launch as portrait . If i want landscape i have to afterwards AGAIN rotate it to landscape .I tried very hard to fix for this but failed . You can download and run the sample code from Apple Developer Site Here . Can anyone fix this code so that if launched in landscape mode it presents the modal view for the landscape view ? Otherwise I'll have to rewrite everything to use a single view controller .
These are the relevant portions of apples code :
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor colorWithRed:197.0/255.0 green:204.0/255.0 blue:211.0/255.0 alpha:1.0];
LandscapeViewController *viewController = [[LandscapeViewController alloc]
initWithNibName:#"LandscapeView" bundle:nil];
self.landscapeViewController = viewController;
[viewController release];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
// We must add a delay here, otherwise we'll swap in the new view
// too quickly and we'll get an animation glitch
[self performSelector:#selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
[self dismissModalViewControllerAnimated:YES];
isShowingLandscapeView = NO;
}
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{return (interfaceOrientation == UIInterfaceOrientationPortrait); // support only portrait}
I know this is probably no longer relevant to you, but I just came across the same glitch and here's my solution.
From the way you have your code set out (including how Apple sets it out)
- (void)updateLandscapeView
is only called once a Notification is sent out telling the ViewController of an orientation change: the issue here is, that this is the method responsible for checking the orientation it self. (i.e. Starting the application this method is not called and therefore it doesn't check whether the device is in any other orientation)
The solution is quite simple: Force cal themethod at launch, i.e. in viewDidLoad . . .
[self updateLandscapeView]
This will force call the method and check the interfaces orientation, after the first time, the method will be called again when ever it receives a notification for a changed Orientation
Hope this helps someone Out There
It seems that the device assumes portrait unless you specify landscape only in settings. Your only option would be in your portrait view in the loadview method to detect the orientation and to swap views during launch.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ) {
//Load vertical interface
}
else
{
//load landscape
}
}
How would I have one view up when the iPhone is in a standard 'portrait' orientation, and switch to a different view (say a graph or something) when rotated to a landscape orientation and visa versa?
Disable orientation for that view (assuming that the first view is landscape)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)||(interfaceOrientation == UIInterfaceOrientationLandscapeRight); }
Then add this to the viewDidAppear
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
And add this method somewhere
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
// Present View Controller here
break;
default:
break;
};
}
And on the other view do the same but backwards with a dismiss for landscape instead of the present for portrait.
Dont forget to unregister for the notifications.
(alternatively use a navigation view with both controls but without the bar and simply show the one you want depending on the orientation using)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
First read how UIViewControllers work:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Then, in your UIViewController subclass, take advantage of willRotateToInterfaceOrientation:duration: to change out your views.
e.g.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// if portrait
[self.landscapeView removeFromSuperview];
[self.view addSubview:self.portraitView];
// if landscape
[self.portraitView removeFromSuperview];
[self.view addSubview:self.landscapeView];
}
And add in the appropriate if statement or switch case to determine which to do.