Rotation behaving differently on iOS6 - ios

I did an App which is tab-based. Nothing needs to be on landscape mode but a couple of views. It worked OK on iOS5 and I was pretty happy with the result. However with iOS6 and without messing with anything, it now rotates all the views and the consequences are not nice.
Because its a tab-based app, the couple of view I need in landscape are modalViews. That way I didn't mess with the tabbar and I had only to chose portrait in the "Supported Orientations" setting on build options and set:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
on the views I wanted landscape.
Now with iOS6 this views are also on portrait mode, no matter what and they do not show the landscape mode even if I rotate the device. Likewise, if I allow all the orientations on the "Supported orientations", they all rotate, no matter what I put on the method above.
On all the views I haven't check the box "Use Autolayout" on storyboards.
Any help here?
*EDIT**
Now that I see it, the App I have on the device works fine. I've installed with a promo code, not from Xcode, only to see whether my customers are having problems or not. Fortunatelly they are not. The problem remains though.

The most important part of the documentation I found for this issue is:
When the user changes the device orientation, the system calls this
method on the root view controller or the topmost presented view
controller that fills the window
To make my app fully working for autorotation in iOS 6, I had to do the following:
1) I created a new subclass of UINavigationController, and added shouldAutorotate and supportedInterfaceOrientation methods:
// MyNavigationController.h:
#import <UIKit/UIKit.h>
#interface MyNavigationController : UINavigationController
#end
// MyNavigationController.m:
#import "MyNavigationController.h"
#implementation MyNavigationController
...
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
...
#end
2) In the AppDelegate, I did use my new subclass to show my root ViewController (it is introScreenViewController, a UIViewController subclass) and did set the self.window.rootViewController, so it looks that:
nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController];
nvc.navigationBarHidden = YES;
self.window.rootViewController = nvc;
[window addSubview:nvc.view];
[window makeKeyAndVisible];

This is the alternative solution for iOS6 in case you are using the tab bar controller. It also shows that is NOT needed to override UINavigationController or even UITabBarController.
In your xyzAppDelegate.h add this interface:
#interface UITabBarController (MyApp)
#end
And in xyzAppDelegate.m add these methods:
#implementation UITabBarController (MyApp)
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
// your custom logic for rotation of selected tab
if (self.selectedIndex==...) {
return UIInterfaceOrientationMaskAll;
}
else {
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
}
}
#end
Also, set the root view controller for the app window:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[self.window setRootViewController:tabBarController];

Are you setting the rootViewController in the delegate? For example,
self.window.rootViewController = self.navigationController;
When I was doing some iOS6 testing it wouldn't work properly until I did that...

I have a good solution for cross 5.0 to 6.0 working - All of the above with
-(BOOL)shouldAutorotate{return [self shouldIRotateAnyiOS];}//iOS6
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{return [self shouldIRotateAnyiOS];}//pre iOS6
-(BOOL)shouldIRotateAnyiOS{
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
//do the rotation stuff
return YES
}

You might double check Support Interface Orientations
On previous version, it means nothing, but affects whole application now.
Note: The 'upside down' option doesn't work even enabled or disabled on iOS 6.

This is what works for me.
I created a new subclass of UINavigationController, and added shouldAutorotate and supportedInterfaceOrientation methods:
#import "MyNavigationController.h"
#interface MyNavigationController ()
#end
#implementation MyNavigationController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
#end
Then add this to your delegate
UINavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:_viewController];
nvc.navigationBarHidden = NO; // YES if you want to hide the navigationBar
self.window.rootViewController = nvc;
[_window addSubview:nvc.view];
[_window makeKeyAndVisible];
Now you can add this to the views you want to rotate in all orientations
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Or add this to the views you only want to go portrait and portraitUpsideDown
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return
(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ;
}
- (BOOL)shouldAutorotate
{
return YES;
}

There are a few things you may need to handle to get this working since with iOS6 the structure of autorotate has changed. The structure of how autorotate is determined is now reversed. It used to be that an individual view controller can control the autorotate with its decision but now the "shouldAutorotate" is determined by the highest parent in the navigation which in your case is the tabBar.
You need to make sure your window has a rootViewController set and not just added as a subview.
You may need to subclass your tabBarController to implement both "supportedInterfaceOrientations" and "shouldAutorotate".
If there are any viewControllers that need to behave differently then you will need to have your tabBarController consult with them for the answer on whether they should autorotate.
for example:
- (BOOL)shouldAutorotate
{
return self.selectedViewController.shouldAutorotate;
}
and in your view controller you would implement shouldAutorotate and make the decision there.

From Apple's documentation for shouldAutorotateToInterfaceOrientation:
Override the supportedInterfaceOrientations and preferredInterfaceOrientationForPresentation methods instead.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instm/UIViewController/shouldAutorotateToInterfaceOrientation:

For app "Same Picture" on iOS6 I need an orientation change, my UIViewController never be informed for orientation, it's an photo overlay likely didrotate works well :
- (void)didRotate: ( NSNotification* )note
{
[self performSelector:#selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}
I make fine size adjust with delayed call. From notification it's easy to know final orientation

Did a little experimentation: Took an existing app (that wouldn't rotate in iOS-6, but did previously) and added the one line self.window.rootViewController = navCtlr; to AppDelegate. This resulted in an app that appears (at least at first blush) to rotate just fine.
Then, out of curiosity, I created the RotationCanary class and plugged an instance of that into self.window.rootViewController. I'd start up the app and wait for the inevitable "unrecognized selector", create a new method of that name in RotationCanary, and re-run. The new method would call the real nav ctlr and log its response before returning it. This produced (sooner than I expected) the following log:
2012-12-07 13:08:47.689 MyTestApp[53328:c07] System Version is 6.0; Supported versions are 5.0.x to 6.0.x
2012-12-07 13:08:47.691 MyTestApp[53328:c07] Host memory (in bytes) used: 3489513472 free: 803893248 total: 4293406720
2012-12-07 13:08:47.692 MyTestApp[53328:c07] Memory in use by task (in bytes): 23719936
2012-12-07 13:08:47.695 MyTestApp[53328:c07] Creating database
2012-12-07 13:08:47.699 MyTestApp[53328:c07] Item Selected: (null) (null)
2012-12-07 13:08:47.700 MyTestApp[53328:c07] <DetailViewController.m:(27)> Entering Method -[DetailViewController viewDidLoad]
2012-12-07 13:08:47.706 MyTestApp[53328:c07] <SplitContentViewController.m:(57)> Entering Method -[SplitContentViewController viewDidLoad]
2012-12-07 13:08:47.708 MyTestApp[53328:c07] <FamilyMasterViewController.m:(32)> Entering Method -[FamilyMasterViewController viewDidLoad]
2012-12-07 13:08:47.709 MyTestApp[53328:c07] <MasterViewController.m:(41)> Entering Method -[MasterViewController viewDidLoad]
2012-12-07 13:08:47.718 MyTestApp[53328:c07] <FamilyHomeDetailViewController.m:(51)> Entering Method -[FamilyHomeDetailViewController viewDidLoad]
2012-12-07 13:08:47.820 MyTestApp[53328:c07] -[RotationCanary _preferredInterfaceOrientationGivenCurrentOrientation:] - current = 2, result = 2
2012-12-07 13:08:47.821 MyTestApp[53328:c07] -[RotationCanary _existingView] - view = (null)
2012-12-07 13:08:47.824 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.825 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.826 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary wantsFullScreenLayout] - result = YES
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.830 MyTestApp[53328:c07] -[RotationCanary _tryBecomeRootViewControllerInWindow:] - window = <UIWindow: 0x9c76320; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x9c76450>>, result = YES
2012-12-07 13:08:47.916 MyTestApp[53328:c07] -[RotationCanary _deepestDefaultFirstResponder] - result = <SignOnViewController: 0x9c942a0>
2012-12-07 13:08:47.916 MyTestApp[53328:c07] Device model: x86_64
Curiously, the class was never actually invoked to perform rotation -- only during setup.
I suspect that Apple uses the setting of rootViewController purely as a way to indicate that the app has been modified for iOS 6 rotation -- it has no real function otherwise.
FWIW: It occurred to me that the caller might be using respondsToSelector and skipping some calls, so I added an implementation of resolveInstanceMethod: to RotationCanary, to trap any such attempts. None occurred.

Autorotation changed in iOS 6.0. Check this link for more information.
Autorotation is changing in iOS 6. In iOS 6, the shouldAutorotateToInterfaceOrientation:
method of UIViewController is deprecated. In its place, you should use the
supportedInterfaceOrientations and shouldAutorotate methods.

This code common for ios5 and ios6
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
[self performSelector:#selector(setframeLandscap) withObject:nil afterDelay:0.2];
}
else {
[self performSelector:#selector(setframePortrait) withObject:nil afterDelay:0.2];
}
}
-(BOOL)shouldAutorotate {
return YES;
}

Related

ZBarReaderViewController reader view changes orientation for iOS6 & iOS7 even after restricting it by _reader.supportedOrientationsMask

I am using ZBarSDK for QR Code scanning feature. I want to use this only in PORTRAIT mode only. As per the documentation I set it up with below code line:
_reader.supportedOrientationsMask = ZBarOrientationMask(UIInterfaceOrientationPortrait);
As expected it works well with iOS 5 but with the same code this view changes orientation for iOS 6 & 7. Is supportedOrientationsMask only works with < iOS 6? Is there any other way to force this ZBar reader camera view to work only in Portrait mode? Thanks in advance
Here more details with Code:
if(_reader) // first check `_reader` is created or not?
{
[_reader.readerView stop]; // then stop continue scanning stream of "self.ZBarReaderVC"
for(UIView *subViews in _reader.view.subviews) // remove all subviews
[subViews removeFromSuperview];
[_reader.view removeFromSuperview];
_reader.view = nil;
}
_reader = [ZBarReaderViewController new];
_reader.readerDelegate = self;
_reader.supportedOrientationsMask = ZBarOrientationMask(UIInterfaceOrientationPortrait);
ZBarImageScanner *scanner = _reader.scanner;
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
[_reader.view setFrame:CGRectMake(0, _topbar.frame.size.height, self.view.bounds.size.width, self.view.bounds.size.height-_topbar.frame.size.height)];
_reader.cameraOverlayView = [self CommomOverlay];
_reader.showsZBarControls=NO;
// present and release the controller
[self presentModalViewController: _reader
animated: NO];
Let me know in case more details required.
Finally found the solution.
The problem was like this:
ZbarViewController *reader was presented from my current view controller and it's portrait support property was not working somehow.
_reader.supportedOrientationsMask = ZBarOrientationMask(UIInterfaceOrientationPortrait);
What i did to resolve this issue is I created TBZbarViewController the new class which was inheriting the ZbarViewController class and placed the below method.
-(BOOL)shouldAutorotate{
return NO;
}
Then I used the TBZbarViewController *reader to present from My controller which solved the issue and it's working in Portrait mode only as needed.
Thanks.
I did like this, and is working for all iOS versions :
Step 1 : Set your Device Orientation
Step 2 : Add this code into you implementation (.m) file.
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
- (BOOL) shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
#endif
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}

iOS7 viewController and MPMoviePlayerViewController Rotation

I try a lot of things, but I still can't rotate only 1 viewControllor in all my app.
I would like to show (or to rotate) in landscape only a vc with a MPMoviePlayerViewController.
Like the videos in Facebook app. The app is only in portrait but video could rotate.
After played the video, application return in portrait mode.
I'm able to ratate but after "done" videoplayer button clicked the view return in landscape mode.
How can I fix this?
Thank you very much.
Create new View controller for Playing videos
Click on Project then click on Target. In General category under Deployment Info enable All the rotations
Now open your Root view controller and Put following lines.give what orientation of your app
code:
-(BOOL)shouldAutorotate
{
return TRUE;
}
-(NSUInteger)supportedInterfaceOrientations
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
return UIInterfaceOrientationMaskPortrait;
}
else
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
}
4.Now if you used addsubview method to represent your other ViewController's views then no need to apply orintation methods to other controller. But If any vc you have used PresentController method then add orientation methods to that conroller
Create a new UIViewController that you will use for showing a video.
Create a MPMoviePlayerController property
#property (nonatomic, strong) MPMoviePlayerController* moviePlayerController;
Then in viewDidLoad, try this:
- (void)viewDidLoad
{
[super viewDidLoad];
_moviePlayerController = [[MPMoviePlayerController alloc] init];
_moviePlayerController.controlStyle = MPMovieControlStyleFullscreen;
_moviePlayerController.contentURL = [NSURL URLWithString:#"example.com"];
// Rotating the player to landscape position
_moviePlayerController.view.frame = CGRectMake(0.0f,
0.0f,
[UIScreen mainScreen].bounds.size.height,
[UIScreen mainScreen].bounds.size.width);
_moviePlayerController.view.transform = CGAffineTransformMakeRotation(M_PI_2);
_moviePlayerController.view.center = self.view.center;
UIView *playerView = _moviePlayerController.view;
[self.view insertSubview:playerView atIndex:0];
[_moviePlayerController prepareToPlay];
}
Hope it helps.

UIImagePickerController not full screen

Since the iOS7 upgrade, I have a weird behaviour of the UIImagePickerController. In this application I am using the UIImagePickerController with a cameraOverlayView.
In iOS6 I called the UIImagePickerController using the following code:
_picker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) {
_picker.sourceType = UIImagePickerControllerSourceTypeCamera;
_picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
_picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
_picker.showsCameraControls = NO;
_picker.navigationBarHidden = NO;
_picker.toolbarHidden = YES;
_picker.wantsFullScreenLayout = YES;
_overlayViewController = [[OverlayViewController alloc] init];
_overlayViewController.picker = _picker;
_overlayViewController.frameSize = self.frameSize;
_overlayViewController.delegate = self;
_picker.cameraOverlayView = _overlayViewController.view;
}
else {
_picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
_picker.delegate = self;
Where the OverlayViewController is an UIViewController, with a transparent background which draws some custom controls on screen.
But now in iOS 7 the camera is drawn through the statusbar and a black bar appears beneath the live camera view.
I can solve this by applying a CGAffineTransformMakeTranslation to the cameraViewTransform property of the UIImagePickerController, but why is this like this?
In iOS 7, by default UIViewController views take up the entire screen area including the status bar.
wantsFullScreenLayout
is deprecated and ignored. In some cases, this fix works (in the view controller class):
if ([self respondsToSelector:#selector(setEdgesForExtendedLayout:)]) {
[self setEdgesForExtendedLayout:UIRectEdgeNone];
}
In other cases, it's a bit more complicated. It's late here, so see how you go with it. Helpful things to note - in a UIViewController, the following code will give the correct statusbar height on both iOS 6 and iOS 7, should it come to having to align things using CGRect math:
if (UIDeviceOrientationIsLandscape(self.interfaceOrientation)) {
statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.width;
} else {
statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
}
And then don't forget that in Interface Builder, there are the new "iOS 6 delta" adjustments that allow you to design for iOS 7 and then use offsets to correct for iOS 6.
Anyhow, let me know how you go.
My understanding of the issue, based on a few other SO threads and such, is that UIImagePickerController does not do what we'd expect in terms of managing the status bar via [UIViewController -prefersStatusBarHidden].
This means you either have to disable view controller status bar management entirely, via plist, or figure out a way to get UIImagePickerController to do what we want. On the assumption that you're not looking for the former, I can say I've had success in the latter by putting the picker in a wrapper controller that does what I want (but fall back to your previous code if you still need to detect/support iOS6):
#interface PickerContainer : UIViewController
#property ( nonatomic, weak ) UIImagePickerController* picker;
#end
#implementation PickerContainer
- (void) setPicker: (UIImagePickerController*) picker
{
[self addChildViewController: picker];
[picker didMoveToParentViewController: self];
self->_picker = picker;
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.picker.view.frame = self.view.bounds;
[self.view addSubview: self.picker.view];
}
// Will have no effect in ios6 -- see [-init] for that option
- (BOOL) prefersStatusBarHidden { return YES; }
- (id) init
{
if ( ! ( self = [super init] ) ) return nil;
if ( detectThatThisIsIos6() ) self.wantsFullScreenLayout = YES;
return self;
}
#end
This will work for you, scaled camera, you will have a black bar at the bottom but it will get overlayed by tool bar
https://stackoverflow.com/a/15803947

Camera Image Picker controls - Auto Rotation in iOS7

I have a photo app that overlays custom button on camera image picker (for taking picture, turning on/off the flash, other usual stuff etc.)
I want the control interface to support portrait orientation only (I am talking about the control button/interface only, and not the actual captured image), which was working fine till iOS 6.
However, having upgraded to xCode version 5.0 and having upgraded my iPad 3 to iOS 7 (GM Seed, for iPad WiFi 3rd Generation), I find that the camera picker interface auto-rotates when orientation is changed. Surprisingly, I tested the same build on an iPhone 5 (upgraded to iOS 7), but the auto-rotation problem did not manifest itself.
[To be double sure, I tested the same piece of code in iOS 6 again, and the auto-rotation did not happen, neither in iPhone or iPad].
Just to demonstrate how I handle my image picker, here's a bit of code snippet:
UIImagePickerController *pickercustom = [[UIImagePickerController alloc] init];
pickercustom.sourceType = UIImagePickerControllerSourceTypeCamera;
pickercustom.showsCameraControls = NO;
pickercustom.wantsFullScreenLayout = YES;
pickercustom.navigationBarHidden=YES;
pickercustom.view.userInteractionEnabled=YES;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
if (IPAD.userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
pickercustom.delegate = self;
UIDevice *currentDevice = [UIDevice currentDevice];
while ([currentDevice isGeneratingDeviceOrientationNotifications])
[currentDevice endGeneratingDeviceOrientationNotifications];
[self presentViewController:pickercustom animated:YES completion:nil];
while ([currentDevice isGeneratingDeviceOrientationNotifications])
[currentDevice endGeneratingDeviceOrientationNotifications];
}
else
{
pickercustom.delegate = self;
[self presentViewController:pickercustom animated:YES completion:nil];
}
}
The 'endGeneratingDeviceOrientationNotifications' was added to stop the interface from rotating (which hitherto worked fine).
I also tried adding these three methods after reading this: UIImagePickerController in iOS 6 doesn't work properly
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
...but this was, perhaps, an iOS 6 specific solution. It didn't work in my case.
Please let me know if you could figure out the root cause. It would be great help.
You are close. When you want to support rotation but want that one viewController to not rotate, things get tricky:
The UIResponder chain REALLY wants the whole app to have the same rotation. Just simply overriding the rotation delegate methods in your single class will not work. (FYI, in your case, you will need to subclass UIImagePickerController in order to add those methods.) You need to implement these delegate methods in your root navigation controller (You'll need to have your own sub-class, again), and override them to query the top-most viewController for its desired rotation. Something like:
// Handles the should Auto Rotation for all view controllers
- (BOOL)shouldAutorotate {
if ([self.topViewController conformsToProtocol:#protocol(CustomRotation)]) {
return [self.topViewController shouldAutorotate];
}
// Auto rotate the screen by default.
return YES;
}
// Handles the supported Interface Orientations for all View Controllers by seeing if
// the top level viewController responds to Custom Rotation callbacks.
- (NSUInteger)supportedInterfaceOrientations {
if ([self.topViewController conformsToProtocol:#protocol(CustomRotation)]) {
return [self.topViewController supportedInterfaceOrientations];
}
// The default rotation for the application.
return UIInterfaceOrientationMaskAll;
}
You can't use respondsToSelector: in place of conformsToProtocol: because the selector method will always return YES for any class that derives from UIResponder (so like, everything), and you'll have to override the rotation delegates on each and every UIViewController in your project to make this work. Instead, you can create a blank protocol (CustomRotation). In your custom rotation class require that protocol and include the overridden rotation delegate methods like you have above, with the your desired restrictions.
Lastly make sure your supported interface orientations are set properly in xcode and/or in your Application: didFinishLaunchingWithOptions method.
As far as R&D done by me for the same topic,Imagepicker Camera in IOS7 iPad have default interface to change orientation to landscape .They have designed interface in such a way.We cannot forcefully lock the orientation of it.
If still willing to do you have to use custom ImagePicker use AVCam https://developer.apple.com/library/ios/samplecode/avcam/Introduction/Intro.html
and Custom image picker...
http://www.codza.com/custom-uiimagepickercontroller-camera-view
and forcefully lock there orientation...

Specific Orientation Background

Here my code for specifying the background in ipad iOS6,
- (void)viewDidLoad
{
if ([[UIScreen mainScreen] bounds].size.height == 1024)
{
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"homeipad.png"]];
}
else if ([[UIScreen mainScreen] bounds].size.height == 768)
{
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"landscapipad.png"]];
}
}
its not changing depends on orientation?I have included
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
How to allocate specific background image for corresponding orientation in ipad?
Remember viewDidLoad is called only when you make a new UIViewController object in the memory and you push/present that controller object.
the method name viewDidLoad defines that your viewcontroller view is loaded. Now you can perform the all initialization tasks here.
Answer to your question.
The following UIVIewController's delegate methods will help you in this. These methods are called every time when device changes its orientation.
// Called before interface rotation
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
// Called after interface rotation
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
One more thing, rather than comparing screen height , you can check the current orientation from the above two methods.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
{
if( UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
{
// Your code goes here for landscape orientation
}
else
{
// Your code goes here for portrait orientation
}
}

Resources