"Interfaceorientation" Is Deprecated in iOS 8, How to Change This Method Objective C

interfaceOrientation is deprecated in iOS 8, How to change this method Objective C

Getting the device orientation is not correct. For instance, the device might be in landscape mode, but a view controller that only supports portrait will remain in portrait.

Instead, use this:

[[UIApplication sharedApplication] statusBarOrientation]

Another bonus is that it still uses the UIInterfaceOrientation enum, so very little of your code needs to change.

InterfaceOrientation deprecated in iOS 8

Since iOS8, Apple recommends to use TraitCollections (Size Classes) instead of interfaceOrientation.

Moreover, since iOS 9 and the new iPad feature "Multitasking", there are some cases where the device orientation doesn't fit with the window proportions ! (This leads to brake your application UI)

However, sometimes TraitCollections doesn't fill all your design needs. For those cases, Apple recommends to compare view's bounds :

if view.bounds.size.width > view.bounds.size.height {
// ...
}

I was quite surprised, but you can check on the WWDC 2015 video Getting Started with Multitasking on iPad in iOS 9 at 21'15.

didRotateFromInterfaceOrientation is deprecated in iOS 8

The following should be able to handle orientation of video preview properly in swift 2.1:

override func viewWillAppear(animated: Bool) {
super.viewDidLoad()

NSNotificationCenter.defaultCenter().addObserver(self,
selector: Selector("deviceOrientationDidChange:"),
name: UIDeviceOrientationDidChangeNotification,
object: nil)
}

override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
super.viewDidDisappear(animated)
}

func deviceOrientationDidChange(sender: AnyObject) {
let deviceOrientation = UIDevice.currentDevice().orientation;
switch (deviceOrientation)
{
case .Portrait:
previewLayer.connection.videoOrientation = .Portrait
case .LandscapeLeft:
previewLayer.connection.videoOrientation = .LandscapeRight
case .LandscapeRight:
previewLayer.connection.videoOrientation = .LandscapeLeft
case .PortraitUpsideDown:
previewLayer.connection.videoOrientation = .PortraitUpsideDown
default:
break
}
}

Device interface orientation

Interface Orientation

You can get good information about orientation before didFinishLaunchingWithOptions is called...

- (BOOL)application:(UIApplication *)application 
willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

Here you can interrogate the UIScreen and UIApplication:

[UIScreen mainScreen].bounds
[UIApplication sharedApplication].statusBarOrientation

These will give you the correct width, height and interfaceOrientation based on the OS state when the app was launched. (It's best to avoid viewController.interfaceOrientation in any case, as it is deprecated in iOS8.)

In your question you suggest statusBarOrientation is incorrect, but it's working fine for me on iPad mini / 8.3.

Device Orientation

If you are interested in device orientation, you need to start listening for device orientation notifications. You can do this either in your app delegate on in a view controller - either way makes no difference to how soon you will get the information, as the device orientation polling takes time to start up. In addition the first device orientation callback you get can be wrong if you are face up / face down: I think it simply takes a cue from the interface orientation.

This is how you start listening:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(deviceOrientationDidChange:)
name: UIDeviceOrientationDidChangeNotification
object: nil];

If you check for deviceOrientation before the first callback, it will be uninitialised so not much use to you. You should stop listening when you are done as this process consumes additional energy.

Here are some logs from a startup sequence, iPad lying face up in landscape orientation:

12:44:39.162 [AppDelegate application:willFinishLaunchingWithOptions:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.165 [AppDelegate application:didFinishLaunchingWithOptions:]
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.179 [ViewController viewDidLoad]
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.180 [ViewController viewWillAppear:]
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.186 [ViewController deviceOrientationDidChange:]
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationLandscapeRight / 4

12:44:39.204 [ViewController viewDidAppear:]
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationLandscapeRight / 4

12:44:39.249 [ViewController deviceOrientationDidChange:]
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationFaceUp / 5

The first callback from deviceOrientationDiDChange takes place ~35ms after startup. If the device is lying flat, that first callback is incorrect - and the correct callback takes place ~20ms later. These first deviceOrientation notifications tend to happen between viewWillAppear and viewDidAppear on the first viewController (but these events are not corellated).

For comparision, here is a startup with iPad lying face up in portrait orientation:

12:44:01.741 [AppDelegate application:willFinishLaunchingWithOptions:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.745 [AppDelegate application:didFinishLaunchingWithOptions:]
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.758 [ViewController viewDidLoad]
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.759 [ViewController viewWillAppear:]
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.765 [ViewController deviceOrientationDidChange:]
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationPortrait / 1

12:44:01.784 [ViewController deviceOrientationDidChange:]
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationFaceUp / 5

12:44:01.828 [ViewController viewDidAppear:]
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationFaceUp / 5

Logging

[UIScreen mainScreen].bounds.size 
[UIApplication sharedApplication].statusBarOrientation
[UIDevice currentDevice].orientation

with some ENUM->NSString lookups

iPhone Interface Orientation on iOS8

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).

Rotation methods deprecated, equivalent of 'didRotateFromInterfaceOrientation'?

Okay found it, just have to use the animateAlongsideTransition:completion: method on the passed UIViewControllerTransitionCoordinator.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// do whatever
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
{

}];

[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

How to know current interfaceOrientation in extension of iOS 8?

A UITraitCollection object provides details about the characteristics of a UIViewController object, which manages a set of views that make up a portion of your app’s interface. These characteristics, or traits, define the size class, display scale, and device idiom of the view controller. When a view controller is created, a trait collection is automatically created for that view controller.

You can create and modify a view controller’s trait collection to customize your app. The following methods create a new trait collection containing only the passed parameter:

traitCollectionWithDisplayScale:

traitCollectionWithUserInterfaceIdiom:

traitCollectionWithHorizontalSizeClass:

traitCollectionWithVerticalSizeClass:


Related Topics



Leave a reply



Submit