ipad app won't rotate in IOS6 - ios

I have a UISplitViewController ipad app. It uses a mainwindow.xib and my subclassed RootView and DetailView controllers. It autorotates properly in all ioses up to 5.1.
I know the interface changed for ios6. When I add the new rotation methods to my detail and rootview classes it still does not rotate.
My supportedInterfaceOrientations method is called, but shouldAutorotate is never called.
Does anyone know how to fix this?
(Always learning that no one can mess you around as badly as another programmer. Thanks Apple.)
Gerry

From the iOS 6 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.
I know that's a mouthful but you might also want to check the supported interface orientations sheet in your project's settings:

Try to set up a notification when orientation changed.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Then implement the rotation inside orientationChanged function.
- (void)orientationChanged:(NSNotification *)notification {}

Related

Presenting avplayer horizontally

Is there any way to allow landscape mode in only one view controller in an app? I'm presenting it modally like so:
let recViewController = AVPlayerViewController()
recViewController.modalTransitionStyle = .CoverVertical
recViewController.player = AVPlayer(URL: NSURL(string: currentScores[selectedButtonIndexPath.row].recapAvailable))
recViewController.player.play()
self.view.window?.rootViewController?.presentViewController(recViewController, animated: true, completion: nil)
I know I can manually override each view controller to only allow for vertical orientation (with the exception of the above one) but that seems rather tedious.
Is there any way to allow landscape mode in only one view controller in an app?
You have answered the question yourself, see the 'Configuring the View Rotation Settings' in UIViewController class reference. You need to configure your app to support all of the rotations you want, then override each view controller, and yes it is tedious, but it works :)
Handling View Rotations
As of iOS 8, all rotation-related methods are
deprecated. Instead, rotations are treated as a change in the size of
the view controller’s view and are therefore reported using the
viewWillTransitionToSize:withTransitionCoordinator: method. When the
interface orientation changes, UIKit calls this method on the window’s
root view controller. That view controller then notifies its child
view controllers, propagating the message throughout the view
controller hierarchy.
In iOS 6 and iOS 7, 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.
You can override the preferredInterfaceOrientationForPresentation for
a view controller that is intended to be presented full screen in a
specific orientation.
When a rotation occurs for a visible view controller, the
willRotateToInterfaceOrientation:duration:,
willAnimateRotationToInterfaceOrientation:duration:, and
didRotateFromInterfaceOrientation: methods are called during the
rotation. The viewWillLayoutSubviews method is also called after the
view is resized and positioned by its parent. If a view controller is
not visible when an orientation change occurs, then the rotation
methods are never called. However, the viewWillLayoutSubviews method
is called when the view becomes visible. Your implementation of this
method can call the statusBarOrientation method to determine the
device orientation.
EDIT
You can also look at the UIApplicationDelegate Protocol, it has the method
func application(application: UIApplication,
supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask
From the documentation:
Discussion
This method returns the total set of interface orientations
supported by the app. When determining whether to rotate a particular
view controller, the orientations returned by this method are
intersected with the orientations supported by the root view
controller or topmost presented view controller. The app and view
controller must agree before the rotation is allowed.
If you do not implement this method, the app uses the values in the
UIInterfaceOrientation key of the app’s Info.plist as the default
interface orientations.

Stop autorotation of UIViewController at creation time

Is there any way to set autorotate behavior of an UIViewController object when it's initiated?
I wanted it to never rotate, so I tried this:
UIViewController *myViewController = [[UIViewController alloc]init];
myViewController.shouldAutorotate = NO;
Seemed logical, but it doesn't work. Get the error message:
No setter method 'setShouldAutorotate:' for assignment to property
Or is it possible only through subclassing?
You should this way:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
Return Value
A bit mask specifying which orientations are supported.
See UIInterfaceOrientationMask for valid bit-mask values. The value
returned by this method must not be 0.
Discussion
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. If the view controller supports
the new orientation, the window and view controller are rotated to the
new orientation. This method is only called if the view controller's
shouldAutorotate method returns YES.
Override this method to report all of the orientations that the view
controller supports. The default values for a view controller's
supported interface orientations is set to
UIInterfaceOrientationMaskAll for the iPad idiom and
UIInterfaceOrientationMaskAllButUpsideDown for the iPhone idiom.
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.
Source: UIViewController on iOS Developer Library.

NavigationController willRotateToInterfaceOrientation is not getting called if i change the orientation of the topviewcontroller in iOS 8

My app is navigation based one. I have extended UINavigationController and have implementations of the below methods in NavigationController and individual ViewControllers also.
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
When the orientation change happens In iOS 7, First Rotation method from Navigation controller gets called then the same method from Actual viewcontroller gets called. I badly need this.
In case of iOS8 only Rotation method from Viewcontroller gets called not the Navigation controllers one.
Note: I m not using any ios 8 specific orientation method also. As i have change so many things.So please don't suggest me to implement the below - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id )coordinator
That method is deprecrated from ios 8
Sent to the view controller before performing a one-step user interface rotation.
Use viewWillTransitionToSize:withTransitionCoordinator: to make interface-based adjustments.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
duration:(NSTimeInterval)duration
Also note that by the time we recevice this notification the view is already change to its new orientation.
For more reference https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/willAnimateRotationToInterfaceOrientation:duration:

iOS Orientation Support both Landscape and Portrait on specific screen - NOT ALL Screens

Comrades,
I just would like to know, how to enable Landscape Orientation only on Specific screens? As of now, I selected Landscape Left and Right options in General Settings and enabled in Supported interface orientations (iPhone) in plist file for the device Orientation, but that impacts all the screens.
I have nearly 80 screens in my application, I need to support both Portrait and Landscape about 5 screens, rest of the screens should be shown only in Portrait mode.
Any help is greatly appreciated!
Thanks,
Ramesh
In General Settings (which just adjusts your plist), you need to select all possible supported orientations. Then, you need to limit them in your specific view controller. If you're using a NavBar or TabBar controller, you need add your limitation there.
From the UIViewController docs:
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.
To make this simpler, I created a category on UINavigationController that looks at the top-most view controller to determine it's rotation abilities. That way, in my specific view controllers that needed rotating, I could override those same methods and add landscape support.
#implementation UINavigationController (AutoRotation)
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
#end
Are your screens inside a UINavigationController? If so, I've noticed not all viewControllers can decide what orientations they support.

iOS >> Device Orientation >> Screen is Not Supporting Upside Down

I have a screen that supports Device Orientation.
Everything is working fine except for the fact that when I rotate the device upside down (home button at top), the rotation doesn't work (it's stuck on the last landscape settings).
I know of several places needed be updated to support this:
In the VC itself, I added the methods:
In the Project Target, I updated as follow:
In the Storyboard VC Scene, I updated as follow:
What am I missing here?
You also have to allow rotating to all orientations in every parent view controller of the current main view controller. For example, if your view controller is in navigation controller, try subclassing it and override the same methods as in your example.
Edit: As #JordanC mentioned, since iOS 7 you can implement UINavigationControllerDelegate method to return custom supported orientations:
- (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController
As #eGanges mentioned the key point could be to subclass your UITabBarController (and override supportedInterfaceOrientations) if that is your initial view controller, in that case this is the only controller you should subclass (and of course you should add all the supported interface orientations to your app Info.plist file UISupportedInterfaceOrientations key)
Have you tested on real device?
anyway try this:
- (NSUInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}

Resources