78

I have one UIView which is not using Auto-Layout and some components are displayed based on their percent of X and Y co-ordinates from the main view.

Previously I would have run a function to update their positions in didRotateFromInterfaceOrientation however I see this is now deprecated in iOS8.

I've taken a look at viewWillTransitionToSize but it's giving weird results, and there doesn't appear to be a viewDidtransitionToSize function.

Is there an easy way (in Swift) to run a function after a device rotation?

Richard
  • 1,688
  • 3
  • 16
  • 21

2 Answers2

196

The viewWillTransitionToSize delegate method gets called with a UIViewControllerTransitionCoordinator conforming object. A method that protocol declares is animateAlongsideTransition(_:animation, completion:). You can use that to have code execute after the transition is complete.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: nil) { _ in
        // Your code here
    }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Acey
  • 8,048
  • 4
  • 30
  • 46
  • Shouldn't `super.viewWillTransitionToSize:` be called first? – Behdad Jun 18 '16 at 09:30
  • Yep of cource, my bad. Added. Thanks! – Acey Jun 30 '16 at 17:46
  • Is there a way to call something like this on a view itself, and not it's controller? – ArielSD Dec 01 '17 at 19:02
  • 1
    @ArielSD A view should be rather "dumb," only recalculating its subview layout because something (either directly or indirectly) invoked setNeedsLayout. If you need to do something other than update layout on orientation change, feel free to keep a reference to a view and call whatever method you'd like to directly. – Acey Dec 01 '17 at 20:22
24

Although not asked for here Objective C version:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {

    // change any properties on your views

} completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    if( UIDeviceOrientationIsPortrait(orientation) ) {
        NSLog(@"portrait");
    } else {
        NSLog(@"landscape");
    }  
}];
}
Olivier de Jonge
  • 1,454
  • 2
  • 15
  • 31