iOS8 Interface Rotation Methods not called

2019-03-09 17:00发布

问题:

Since willAnimateRotationToInterfaceOrientation:duration: is deprecated in iOS8, one needs to use viewWillTransitionToSize:withTransitionCoordinator: instead.

However, this method does not get called in my view controller on iOS8. Is there anything else, I need to implement, in order for this callback to work?

I cannot find anything in the documentation. The only thing I could find, was that it belongs to the new UIContentContainer protocol. However, even if I am adding this to the protocols of my controller explicitly, it does not work.

Any ideas?

回答1:

The viewWillTransitionToSize:withTransitionCoordinator: seems to only work if the interface is actually going to change size, meaning we have rotated 90 degrees. If you have a mask on your layout that only allows landscape, when rotation 180 degrees, the interface size doesn't change, so this method doesn't seem to be called.

I have worked around this in my app by instead registering to the UIDeviceOrientationDidChangeNotification notification like:

(In my view controller's viewWillAppear):

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

(An in my viewWillDisappear [remember to unsubscribe])

[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

My deviceOrientationDidChange: looks like:

- (void)deviceOrientationDidChange:(NSNotification *)notification {
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self willRotateToInterfaceOrientation:orientation duration:1.0];
}


回答2:

As per the docs, remember to call super

- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    // ...
}

Otherwise child view controllers will not get the message forwarded on to them.



回答3:

I know this question is a bit old at this point but I think the issue might be solved a different way for some who may come across it. If you are trying to load a view that is part of a DIFFERENT controller by using addSubview(controller.view), you need to also add that controller to the parent as well (possibly the view you are adding to's controller). If you do not add the controller to a parent you will never receive the updates for size changes. We later found out the reason for Apple's API change; with the iPad pro, your SizeClass can change without rotation with the multi-tasking ability. This will also call the method:

viewWillTransitionToSize(size: CGSize, 
        withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

In the parent class, if you override the above method, make sure you call super as well or you will just find another way to beat your head against a wall...