additionalSafeAreaInsets is not accounted for during view controller dismissal, using custom UIViewControllerTransitioningDelegate

So, straight to the problem:

I've created a custom UIViewControllerTransitioningDelegate that I use to animate a view from one view controller, to full-screen in another view controller. Im doing this by creating UIViewControllerAnimatedTransitioning-objects that animate the presented view's frame. And it works great! Except when I try to adjust the additionalSafeAreaInsets of the view controller owning the view during dismissal...

It looks like this property is not accounted for when I'm trying to animate the dismissal of the view controller and its view. It works fine during presentation.

So, what I want is: use additionalSafeAreaInsets to diminish the effect of the safe area during animation, by setting additionalSafeAreaInsets to the "inverted" values of the safe area. So that the effective safe area starts at 0 and "animates" to the expected value during presentation, and starts at expected value and "animates" to 0 during dismissal.

(I'm quoting "animates", since its actually the view's frame that is animated. But UIKit/Auto Layout use these properties when calculating the frames)

Any thoughts on how to battle this issue is great welcome!

The code for the custom UIViewControllerTransitioningDelegate is provided as an attachment.

Answered by Smed1 in 698898022

After some debugging I managed to find a workaround to this problem.

In short, it looks like the safe area is not updated after UIViewController.viewWillDisappearis called, and hence any changes to .additionalSafeAreaInsets is ignored (since these insets modifies the safe area of the view controller's view).

My current workaround is somewhat hacky, but it gets the job done. Since UIViewControllerTransitioningDelegate.animationController(forDismissed...) is called right before UIViewController.viewWillDisappear and UIViewControllerAnimatedTransitioning.animateTransition(using transitionContext...), I start the dismiss animation already in that method. That way the layout calculations for the animation get correct, and the correct safe area is set.

I've attached the code for my custom UIViewControllerTransitioningDelegate with the workaround. Note: I've removed the use of .additionalSafeAreaInsets since its not necessary at all! And I've no idea why I thought I needed it in the first place...

I've also created a new post regarding the issue with safe area. Check it out here: https://developer.apple.com/forums/thread/696875

Removed this answer, as it was not intended

Accepted Answer

After some debugging I managed to find a workaround to this problem.

In short, it looks like the safe area is not updated after UIViewController.viewWillDisappearis called, and hence any changes to .additionalSafeAreaInsets is ignored (since these insets modifies the safe area of the view controller's view).

My current workaround is somewhat hacky, but it gets the job done. Since UIViewControllerTransitioningDelegate.animationController(forDismissed...) is called right before UIViewController.viewWillDisappear and UIViewControllerAnimatedTransitioning.animateTransition(using transitionContext...), I start the dismiss animation already in that method. That way the layout calculations for the animation get correct, and the correct safe area is set.

I've attached the code for my custom UIViewControllerTransitioningDelegate with the workaround. Note: I've removed the use of .additionalSafeAreaInsets since its not necessary at all! And I've no idea why I thought I needed it in the first place...

I've also created a new post regarding the issue with safe area. Check it out here: https://developer.apple.com/forums/thread/696875

additionalSafeAreaInsets is not accounted for during view controller dismissal, using custom UIViewControllerTransitioningDelegate
 
 
Q