I have a app which i want to display in portrait mode. But I only want to show one view in both modes.
I have do this for iOS5 . But in iOS6,i can't able to do this.
I also tried many codes to solved it.
i use navigation in my app & rotate only one view in both mode is not possible in ios6. Either you fixed your rotation for a view or rotate whole app. Am i right?
How can I solve this problem?
in ios6 have you trying with this in plist like bellow image:-
and you can also set at xcode->projectname->summary:-
From Apple's iOS 6 SDK Release Notes:
Autorotation is changing in iOS 6. In iOS 6, the
shouldAutorotateToInterfaceOrientation: method of UIViewController is
deprecated. In its place, you should use the
supportedInterfaceOrientationsForWindow: and shouldAutorotate methods.
More responsibility is moving to the app and the app delegate. Now, iOS containers (such as UINavigationController) do not consult
their children to determine whether they should autorotate. By
default, an app and a view controller’s supported interface
orientations are set to UIInterfaceOrientationMaskAll for the iPad
idiom and UIInterfaceOrientationMaskAllButUpsideDown for the iPhone
idiom.
A view controller’s supported interface orientations can change over time—even an app’s supported interface orientations can change
over time. The system asks the top-most full-screen view controller
(typically the root view controller) for its supported interface
orientations whenever the device rotates or whenever a view controller
is presented with the full-screen modal presentation style. Moreover,
the supported orientations are retrieved only if this view controller
returns YES from its shouldAutorotate method. The system intersects
the view controller’s supported orientations with the app’s supported
orientations (as determined by the Info.plist file or the app
delegate’s application:supportedInterfaceOrientationsForWindow:
method) to determine whether to rotate.
The system determines whether an orientation is supported by intersecting the value returned by the app’s
supportedInterfaceOrientationsForWindow: method with the value
returned by the supportedInterfaceOrientations method of the top-most
full-screen controller. The setStatusBarOrientation:animated: method
is not deprecated outright. It now works only if the
supportedInterfaceOrientations method of the top-most full-screen view
controller returns 0. This makes the caller responsible for ensuring
that the status bar orientation is consistent.
For compatibility, view controllers that still implement the shouldAutorotateToInterfaceOrientation: method do not get the new
autorotation behaviors. (In other words, they do not fall back to
using the app, app delegate, or Info.plist file to determine the
supported orientations.) Instead, the
shouldAutorotateToInterfaceOrientation: method is used to synthesize
the information that would be returned by the
supportedInterfaceOrientations method.
If you want your whole app to rotate then you should set your
Info.plist to support all orientations. Now if you want a specific
view to be portrait only you will have to do some sort of subclass and
override the autorotation methods to return portrait only.
See this example How to force a UIViewController to Portrait orientation in iOS 6
EDIT:
Solutions:
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
Related
I have been trying to do this for 2 weeks, and just found out the reason it's not working:
Deprecated APIs
The following APIs are deprecated:
The UIViewController methods and properties for interface orientation. Traits and size classes replace them, as described in Unified Storyboards for Universal Apps.
From what's new in iOS 8
What I need is: a FirstViewController, which is the rootViewController to my navigationController. The FristViewController should be only available in Portrait mode (not ever ever ever displayed in Landscape).
Then there are a few intermediate ViewControllers in the navigation stack (which support both orientations), until I reach a LastViewController, which should be available only in LandscapeRight mode (and never ever ever in portrait, or another mode).
I have been trying with the following CustomNavigationController, but apparently things changed in iOS8, and I can't get it to work:
- (BOOL)shouldAutorotate { // Available in iOS 6.0 and later
return YES; // // May use topViewController's, but in this app it always returns YES
}
- (NSUInteger)supportedInterfaceOrientations { // Available in iOS 6.0 and later
if (self.topViewController != nil)
return [self.topViewController supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { // Available in iOS 6.0 and later
if (self.topViewController != nil)
return [self.topViewController preferredInterfaceOrientationForPresentation];
else
return [super preferredInterfaceOrientationForPresentation];
}
Thanks!
The problem you are having has nothing whatever to do with iOS 8. Here are some points to note:
You have misunderstood the note about what's deprecated. Only methods with names like willRotate are deprecated, and you are not using them anyway.
Nothing has changed with regard to how supportedInterfaceOrientations works. Make sure you test with beta 4, though, because there was a bug in betas 1-3 that prevented presented view controller orientations from working correctly.
"Then there are a few intermediate ViewControllers in the navigation stack (which support both orientations), until I reach a LastViewController, which should be available only in LandscapeRight"... That is impossible, but not because of iOS 8. What you are describing has been illegal since iOS 6! You cannot have different forced orientations for different view controllers in a navigation stack. Only a presented view controller can force rotation (as I have explained here and in many other answers: https://stackoverflow.com/a/21616025/341994).
Implement - (NSUInteger)supportedInterfaceOrientations appropriately in each of the view controllers in the navigation stack. It does not matter what the UINavigationController's supported orientations are. It ought to respect the supported orientations of its displayed view controller.
Also make sure that the all the necessary orientations are checked in your target's "General -> Deployment Info" configuration section.
I've read many answers on SO but I can't seem to get autorotation working on iOS7.
I only need one view controller to rotate, so I don't want to set rotation settings in my Info.plist.
As I understand Apple's documentation, a single view controller can override global rotations settings (from Info.plist) by simply overriding two methods. Info.plist is set to only allow Portrait, and my view controller implements the following methods:
- (NSUInteger)supportedInterfaceOrientations
{
NSLog(#"%s", __PRETTY_FUNCTION__);
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (BOOL)shouldAutorotate
{
NSLog(#"%s", __PRETTY_FUNCTION__);
return true;
}
I'm seeing those NSLog statements upon rotation but nothing rotates.
If I do configure Info.plist with the proper rotation settings, my view will rotate, but not if I try and rely on my view controller.
Not sure if it matters, but the view I'm trying to rotate is from a .xib using auto layout.
Also, my ViewController is being presented modally and is contained in a navigation controller. I've tried just presenting the view controller by itself and that doesn't work. I've also tried adding a category to UINavigationController to get it's autorotation directions from it's topViewController.
In my case, I had a new iOS7 app with about 30 view controllers created already. I needed auto rotation on just a single modal view controller. I didn't want to have to update the preexisting view controllers.
I selected the orientations I wanted in the plist:
Then I added a category to my app delegate on UIViewController:
#implementation UIViewController (rotate)
-(BOOL)shouldAutorotate {
return NO;
}
#end
Then in the single modal view controller I WANTED to rotate I added this method:
-(BOOL)shouldAutorotate {
return YES;
}
I also discovered, that if my view controller wasn't a modal VC I would need to add category methods on UINavigationController instead, for all VCs that were subsequent to the root view controller, as part of the navigation stack of view controllers - similar to this: https://stackoverflow.com/a/20283331/396429
Simple but it work very fine. IOS 7.1 and 8
AppDelegate.h
#property () BOOL restrictRotation;
AppDelegate.m
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskAll;
}
ViewController
-(void) restrictRotation:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
viewDidLoad
[self restrictRotation:YES]; or NO
You need to set the plist value to all possible values, then limit them as you see fit (in the Navigation Controllers and TabBar Controllers. From the UIViewController class description:
In iOS 6 and later, your app supports the interface orientations
defined in your app’s Info.plist file. A view controller can override
the supportedInterfaceOrientations method to limit the list of
supported orientations. Typically, the system calls this method only
on the root view controller of the window or a view controller
presented to fill the entire screen; child view controllers use the
portion of the window provided for them by their parent view
controller and no longer participate directly in decisions about what
rotations are supported. The intersection of the app’s orientation
mask and the view controller’s orientation mask is used to determine
which orientations a view controller can be rotated into.
I've faced such problem - had only one landscape view in my app.
I've used below code to to handle that.
#import "objc/message.h"
-(void)viewWillAppear:(BOOL)animated{
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationLandscapeLeft);
}
I know this is old but I ended up in a more unique situation where we have 50+ ViewController all over the app that I refused to go through and modify and support the same orientation in all of them but one or 2. Which brings me to my answer. I created a UIViewController category that overrides - (BOOL)shouldAutorotate to always return NO or YES depending on device type etc. (this can be done with supported interface orientations too). Then on the ViewControllers I wanted to support more then just portrait, I swizzled shouldAutorotate to return YES. Then forced the orientation change when the view is dismissed on the parent ViewControllers viewWillAppear method using:
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationPortrait) forKey:#"orientation"].
When all was said and done, I accomplished everything I wanted on a few ViewControllers with < 30 lines of code using a macro for swizzling. Had I done it by replacing shouldAutorotate and supportedInterfaceOrientations on all of the VC's in the application I would have ~250 extra lines of code. and a lot of grunt work adding it in the first place.
My application is navigation based application which is supporting iOS 6. Except a view controller all others will support only portrait mode. Particular view controller alone has to support both landscape and portrait orientations.
I searched lot there are tons of questions for this but none of the answer is suitable for me. If some one knows, kindly guide me
I set the orientation as Portait in Project -> Targets -> Summary -> Supported orientation
First you should use methods for the iOS6 presented in UIViewController documentation if you are making your app for iOS6. Orientation method like shouldAutorotateToInterfaceOrientation is deprecated in iOS6, alternate method for iOS6 is shouldAutoRotate. You should only use the old method if your app is supporting also iOS5.
Second If you are using UINavigationcontroller in your application and you need to have different interface orientations then navigationController could mess up the interface orientation in the application. Possible solution (worked for me) is to implement a custom UINavigationController and override the interface orientation methods within that custom UINavigationController class, this will make your viewControllers rotate according to the orientation you set because your controllers are pushed from the UINavigationController. Don't forget to add those methods in your particular viewController also.
CustomNavigationController.h
#interface CustomNavigationController : UINavigationController
#end
CustomNavigationController.m
#implementation CustomNavigationController
//overriding shouldRotate method for working in navController
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
I really think that the correct way to do it is to set both landscape and portrait as supported orientations, and not allowing a change in the orientation on the VC you don't want to rotate, by returning NO on the
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
if the orientation that was passed to the method was not supposed to be supported.
As mentioned in the comments, this method can no longer be used. You should use :
-(BOOL) shouldAutorotate
And find out the current orientation inside this function and returning NO if you don't want to rotate.
Don't forget to allow your application different Orientations!
otherwise nothing from above will work
Set it in project target on General under Deployment Info section:
I want to support all orientations for all views except for the main view controller. I can't seem to find a way to do that.
I can either support orientation for all views or no views throughout the app. How do you support orientations for certain views throughout the app?
I have not yet worked with an app that needed to act that way you describe, but here is what the Apple Documentation suggests when you need to control orientation support:
Dynamically Controlling Whether Rotation Occurs
Sometimes you may want to dynamically disable automatic rotation. For
example, you might do this when you want to suppress rotation
completely for a short period of time. You must temporarily disable
orientation changes you want to manually control the position of the
status bar (such as when you call the
setStatusBarOrientation:animated: method).
> If you want to temporarily disable automatic rotation, avoid
manipulating the orientation masks to do this. Instead, override the
shouldAutorotate method on the topmost view controller. This method is
called before performing any autorotation. If it returns NO, then the
rotation is suppressed.
Source: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDeviceOrientationChanges/RespondingtoDeviceOrientationChanges.html#//apple_ref/doc/uid/TP40007457-CH7-SW1
Subclass the top most controller .
For example you have a navigation controller as the top most controller then you just need to
subclass UINavigationController and write the following line of code in .m file of the subclass
- (BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
Now overwrite the method - (BOOL)shouldAutorotate for each of the controllers in your project.
Return TRUE for those controller for which you need to do rotation and Return FALSE for those controller for which you dont need to do rotation .
Cheers!!!!!
I have a viewcontroller in which I wanted it to be presented only in portrait, so I did the following in iOS 6:
-(BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
however when I rotate the device, it still turns it to landscape. Any idea where else to check this? I put a break point and it hits supportedInterfaceOrientations, but it still rotates
Do you have a navigation controller? The way that iOS6 determines what can be autorotated has changed. It is correctly asking supportedInterfaceOrientations for your view controller but it is probably asking "shouldAutorotate" to another element in your navigation stack hierarchy and accepting that answer. If your navigationController/tabviewController returns yes to this question then it won't consult with your view controller.
You should also provide the apps supported orientations in the app delegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskPortrait;
}
Make sure you add the root view controller properly (not adding it as a subview), but using the following:
[window setRootViewController:myVC];
Also if your view controller is inside a UINavigationController, you should use this category for the navigationcontroller:
#implementation UINavigationController (autorotate)
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
#end
In iOS 6, only the root view controller of the top most full screen controller is asked about rotation. This includes UINavigationController, this class does not ask it's view controllers, it responds directly. Apple now suggest subclassing UINavigationController to override supportedInterfaceOrientations's output.
Make sure that your project settings and info.plist have only portrait orientation selected as they have a higher priority than the app delegate when checking for supported orientations