I'm trying to implement the new viewWillTransitionToSize
method which has been introduced in iOS 8 (all other rotation methods have been deprecated). I'd like to know what the equivalent of didRotateFromInterfaceOrientation
is now as there are a number of clean up tasks we need to perform and I can't see a block that we can assign to UIViewControllerTransitionCoordinator
in order to be called when 'transition' to a new size finishes. Thanks.

- 9,654
- 6
- 33
- 47
7 Answers
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];
}
-
Will this method call every time we rotate like didRotateFromInterfaceOrientation?. Can you please share me the method you have used. Thank you – ask123 Jun 23 '14 at 07:44
-
2Yes it will. This is what I do: `- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id
)coordinator { [coordinator animateAlongsideTransition:^(id – strange Jun 26 '14 at 18:39context) { UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; // do whatever } completion:^(id context) { }]; [super viewWillTransitionToSize: size withTransitionCoordinator: coordinator]; }` -
@strange: Thats great. It would be nice if you could add the code snippet in the answer itself. It looks congested in the comment – Rashmi Ranjan mallick Oct 13 '14 at 05:41
-
@strange: I have another problem in iOS 8. I have a universal iOS application. This should support all the orientations in iPads and only portrait (home button down) in iPhones. But we need one particular view controller to be locked in landscape mode only in both iPads and iPhones. And once you navigate out of that view controller, it should again support the old orientations. How to achieve this? Please help. – Rashmi Ranjan mallick Oct 13 '14 at 05:49
-
1Thanks - i'll add a swift version as an answer to save people some time – DogCoffee Mar 10 '15 at 08:11
-
Is there a way to remove the animation? – Jessica May 12 '15 at 05:17
-
it will call when you press power button and minimize the app. – Rajneesh071 May 16 '16 at 11:21
-
Holy hell, Apple make it hard, don't they? If it wasn't for Stack Overflow contributors such as yourself, I doubt anyone would make anything of substantial worth with the iOS APIs. It's an absolute mess at this point. – Womble May 17 '16 at 03:11
-
even having this "[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; " at the bottom makes difference – Umit Kaya Aug 18 '16 at 09:53
-
3statusbarorientation is deprecated in iOS 9. What else is the option? – Deepak Sharma Apr 13 '17 at 11:25
-
1@DeepakSharma I'm a little late to the party, but you can use `[UIDevice currentDevice].orientation`. You can also pipe this into `UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)` or `UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)`. Hope this helps! – Jeff Nov 17 '17 at 04:21
The Swift Version of the answer by strange
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in
let orient = UIApplication.sharedApplication().statusBarOrientation
switch orient {
case .Portrait:
println("Portrait")
// Do something
default:
println("Anything But Portrait")
// Do something else
}
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
println("rotation completed")
})
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

- 19,820
- 10
- 87
- 120
-
It's strange because I put this in my ViewController, and it didn't `print` anything to my log. I guess because this method is not being called. Can you think of anything else that would need to be plugged in order for this to work? – Trip Mar 10 '16 at 08:46
-
I just added it to a empty project (Universal App) and it works fine without the need to add anything. Maybe put a log statement at the very beginning of the method and see if its being called. I cannot think of anything that you would need to add. What iOS you running? – DogCoffee Mar 10 '16 at 09:11
-
@DogCoffee..its not getting called. Has it anything to do with Simulator? – Saty Jun 18 '16 at 05:21
-
@Saty works in simulator as well - just checked again then. Works as expected. – DogCoffee Jun 18 '16 at 06:51
-
is there a way to do this without subclassing UIVIewController, because we are doing MVVM-C – Andrius Steponavičius Sep 19 '16 at 10:23
-
1statusbarorientation is deprecated in iOS 9. What else is the option? – Deepak Sharma Apr 13 '17 at 11:28
iOS 10.3 & Swift 3
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (_) in
let orient = newCollection.verticalSizeClass
switch orient {
case .compact:
print("Lanscape")///Excluding iPads!!!
default:
print("Portrait")
}
}, completion: { _ in
print("rotation completed")
})
super.willTransition(to: newCollection, with: coordinator)
}

- 1,758
- 19
- 18
-
Why do you need animation? Can't you check 'newCollection' straight away? – cyanide Sep 16 '18 at 23:33
-
The accepted answer in Swift 3:
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (_) in
let orient = UIApplication.shared.statusBarOrientation
switch orient {
case .portrait:
print("Portrait")
// Do something
default:
print("Anything But Portrait")
// Do something else
}
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
print("rotation completed")
})
super.willTransition(to: newCollection, with: coordinator)
}
It works fine for me

- 1,547
- 21
- 21
-
Doesn't work for me on iOS 10 — it prints the old orientation, not the new one. – Kartick Vaddadi Mar 12 '17 at 02:57
-
1@VaddadiKartick because you should use `let orient = newCollection.verticalSizeClass switch orient { case .compact: print("Lanscape") // Do something default: print("Portrait") // Do something else }` – Mike Glukhov Apr 11 '17 at 11:58
Since the question was: what was the equivalent of didRotateFromInterfaceOrientation
I thought I'd contribute the code below:
@implementation ViewController
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
if (previousTraitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular) {
NSLog(@"User has rotated to landscape");
} else if (previousTraitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
NSLog(@"User has rotated to portrait");
}
}
@end
I was testing on an iPhone in the simulator, but my print statements won't get run if I test using the iPad since the traitsCollection won't change.
This is strange because this is exactly what Apple recommends:
- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
[super traitCollectionDidChange: previousTraitCollection];
if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass)
|| self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass)) {
// your custom implementation here
}
}

- 132,869
- 46
- 340
- 423

- 1,845
- 2
- 22
- 23
-
-
Does this works on iPad where both vertical and horizontal classes are Regular on full screen? – Deepak Sharma Apr 13 '17 at 12:00
-
Your code is not the same as Apple's, you are only testing the vertical size class. – ADG Sep 22 '18 at 18:09
-
It's been a while, looks like the content of the link has changed. – NYC Tech Engineer Oct 11 '18 at 12:25
[[UIApplication sharedApplication] statusBarOrientation]
is deprecated in iOS9 you have to test against UITraitCollection for various devices.
override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if newCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: .Regular)) {
...
}
}

- 535
- 4
- 18
-
6Only the setter was deprecated. An Apple employee posted, "Reading the status bar orientation is not deprecated, only writing to it is. This may have been an error in how we constructed the header if you are seeing this on the getter." (https://forums.developer.apple.com/thread/12937) – Graham Perks Oct 20 '15 at 15:37
-
Isn't the getter also deprecated though. According to the [documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instp/UIApplication/statusBarOrientation) it is. – Groot Jan 05 '16 at 09:11
On the Ipad there is no trait collection change so here is how you detect the rotation from start and completion. Here is the Swift 5 syntax:
override func viewWillTransition(to size: CGSize, with coordinator:
UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { [unowned self] _ in
self.view.backgroundColor = UIColor.blue
print("rotation in progress")
}) { [unowned self] _ in
self.view.backgroundColor = UIColor.green
print("rotation complete")
}
}

- 11
- 3