I am developing an App. There are multiple windows in it. A main window that shows the main UI of the app, and some other util windows that are created dynamically when needed.
All of these windows have their rootviewcontrollers, and they all support all the userinterface orientations.
But when I rotate the device, the windows seemed rotate to the right orientation, but some window has four strange black rectangles along each side.
And the worse thing is that the whole app become freezed, it does not respond to touch event, I need to force quit it.
I did a lot of experiments to find out the cause of this issue in last two months.
I found some truth about this issue:
Good Case:
If the App only has the main window, the issue gone. If the rotation animation completed, the issue gone.
the attachment shows some callstacks when rotation animation completed.
goodcase-animation-callstacks
the rotation animation have 3 steps:
the first
```objc
0 Love2DGameMaker 0x000000010e8d3e22 $s15Love2DGameMaker27SimulatorRootViewControllerC18viewWillTransition2to4withySo6CGSizeV_So06UIViewgJ11Coordinator_ptF + 754
1 Love2DGameMaker 0x000000010e8d5dd8 $s15Love2DGameMaker27SimulatorRootViewControllerC18viewWillTransition2to4withySo6CGSizeV_So06UIViewgJ11Coordinator_ptFTo + 72
2 UIKitCore 0x00007ff8052e4c65 +[UIViewController _performWithoutDeferringTransitionsAllowingAnimation:actions:] + 153
3 UIKitCore 0x00007ff8052fe5a6 -[UIViewController(AdaptiveSizing_Internal) _window:viewWillTransitionToSize:withTransitionCoordinator:] + 867
4 UIKitCore 0x00007ff805d10e43 __59-[UIWindow _rotateToBounds:withAnimator:transitionContext:]_block_invoke + 172
5 UIKitCore 0x00007ff806396494 +[UIView(Animation) performWithoutAnimation:] + 84
6 UIKitCore 0x00007ff805d10ca3 -[UIWindow _rotateToBounds:withAnimator:transitionContext:] + 446
7 UIKitCore 0x00007ff805d13f4b -[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:] + 2044
8 UIKitCore 0x00007ff805d14509 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 642
9 UIKitCore 0x00007ff805d0fcf3 -[UIWindow _internal_setRotatableViewOrientation:updateStatusBar:duration:force:] + 113
10 UIKitCore 0x00007ff805d12120 __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 214
11 UIKitCore 0x00007ff805d11dc2 -[UIWindow _updateToInterfaceOrientation:duration:force:] + 1166
12 UIKitCore 0x00007ff804fe4967 -[_UIScenefbsSceneBasedMetricsCalculator _updateMetricsOnWindows:animated:] + 1822
13 UIKitCore 0x00007ff806017c7e -[UIWindowScene _computeMetricsForWindows:animated:] + 89
14 UIKitCore 0x00007ff806016c85 __55-[UIWindowScene _computeMetrics:withTransitionContext:]_block_invoke + 133
15 UIKitCore 0x00007ff806016e16 -[UIWindowScene _computeTraitCollectionAndCoordinateSpaceForcingDelegateCallback:withAction:] + 360
16 UIKitCore 0x00007ff806016bfa -[UIWindowScene _computeMetrics:withTransitionContext:] + 75
17 UIKitCore 0x00007ff806013123 -[UIWindowScene _computeMetricsAndCrossFadeInLiveResize:withTransitionContext:] + 231
18 UIKitCore 0x00007ff806397e43 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 580
19 UIKitCore 0x00007ff8063980f8 +[UIView(UIViewAnimationWithBlocks) _animateWithDuration:delay:options:factory:animations:completion:] + 20
20 UIKitCore 0x00007ff80558439c +[BSAnimationSettings(UIKit) tryAnimatingWithSettings:fromCurrentState:actions:completion:] + 633
21 UIKitCore 0x00007ff8056f64c3 _UISceneSettingsDiffActionPerformChangesWithTransitionContextAndCompletion + 261
22 UIKitCore 0x00007ff804feb651 -[_UIWindowSceneGeometrySettingsDiffAction _updateSceneGeometryWithSettingObserverContext:windowScene:transitionContext:] + 962
23 UIKitCore 0x00007ff804feb1c9 -[_UIWindowSceneGeometrySettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:] + 1507
24 UIKitCore 0x00007ff804dc04db __64-[UIScene scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke.613 + 877
25 UIKitCore 0x00007ff804dbee90 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:] + 245
26 UIKitCore 0x00007ff804dc0043 -[UIScene scene:didUpdateWithDiff:transitionContext:completion:] + 252
27 UIKitCore 0x00007ff8055b9d76 -[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:] + 466
28 FrontBoardServices 0x00007ff807a18b99 -[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:] + 850
29 FrontBoardServices 0x00007ff807a4caa4 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2 + 149
30 FrontBoardServices 0x00007ff807a26a78 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 213
31 FrontBoardServices 0x00007ff807a4c9dc __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke + 381
32 libdispatch.dylib 0x000000011441758f _dispatch_client_callout + 8
33 libdispatch.dylib 0x000000011441af65 _dispatch_block_invoke_direct + 507
34 FrontBoardServices 0x00007ff807a7635f __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
35 FrontBoardServices 0x00007ff807a76239 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 188
36 FrontBoardServices 0x00007ff807a76387 -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 19
37 CoreFoundation 0x00007ff800429fb3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
38 CoreFoundation 0x00007ff800429ef5 __CFRunLoopDoSource0 + 157
39 CoreFoundation 0x00007ff8004296f2 __CFRunLoopDoSources0 + 215
40 CoreFoundation 0x00007ff800423e27 __CFRunLoopRun + 919
41 CoreFoundation 0x00007ff8004236ad CFRunLoopRunSpecific + 557
42 GraphicsServices 0x00007ff8103da08f GSEventRunModal + 137
43 UIKitCore 0x00007ff805cc0ad1 -[UIApplication _run] + 972
44 UIKitCore 0x00007ff805cc5551 UIApplicationMain + 123
45 UIKitCore 0x00007ff804d3f563 __swift_destroy_boxed_opaque_existential_1Tm + 10307
46 Love2DGameMaker 0x000000010e96537b $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 123
47 Love2DGameMaker 0x000000010e9652f7 $s15Love2DGameMaker11AppDelegateC5$mainyyFZ + 39
48 Love2DGameMaker 0x000000010e965448 main + 24
49 dyld 0x000000011132b3e0 start_sim + 10
50 ??? 0x000000011b37e366 0x0 + 4751614822
```
the second:
```objc
0 Love2DGameMaker 0x000000010e8d38b0 $s15Love2DGameMaker27SimulatorRootViewControllerC21viewDidLayoutSubviewsyyF + 4656
1 Love2DGameMaker 0x000000010e8d3b1c $s15Love2DGameMaker27SimulatorRootViewControllerC21viewDidLayoutSubviewsyyFTo + 28
2 UIKitCore 0x00007ff8063a4980 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2654
3 QuartzCore 0x00007ff80b18e261 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 527
4 QuartzCore 0x00007ff80b187623 -[CALayer layoutIfNeeded] + 333
5 UIKitCore 0x00007ff8052f525f __86-[UIViewController window:willAnimateRotationToInterfaceOrientation:duration:newSize:]_block_invoke + 52
6 UIKitCore 0x00007ff806397e43 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 580
7 UIKitCore 0x00007ff806398487 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 25
8 UIKitCore 0x00007ff8052f51f4 -[UIViewController window:willAnimateRotationToInterfaceOrientation:duration:newSize:] + 337
9 UIKitCore 0x00007ff8052fe6a8 __104-[UIViewController(AdaptiveSizing_Internal) _window:viewWillTransitionToSize:withTransitionCoordinator:]_block_invoke.3770 + 54
10 UIKitCore 0x00007ff805308490 -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] + 145
11 UIKitCore 0x00007ff805303a9c -[_UIViewControllerTransitionContext __runAlongsideAnimations] + 276
12 UIKitCore 0x00007ff806397e43 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 580
13 UIKitCore 0x00007ff806398487 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 25
14 UIKitCore 0x00007ff805325d3f __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke_2 + 276
15 UIKitCore 0x00007ff80639c5cd +[UIView _performBlockDelayingTriggeringResponderEvents:forScene:] + 203
16 UIKitCore 0x00007ff805325acf __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke + 161
17 UIKitCore 0x00007ff806399647 +[UIView(UIViewAnimationWithBlocksPrivate) _modifyAnimationsWithPreferredFrameRateRange:updateReason:animations:] + 166
18 UIKitCore 0x00007ff806397e43 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 580
19 UIKitCore 0x00007ff806398487 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 25
20 UIKitCore 0x00007ff80532592f -[_UIWindowRotationAnimationController animateTransition:] + 602
21 UIKitCore 0x00007ff805d10d68 -[UIWindow _rotateToBounds:withAnimator:transitionContext:] + 643
22 UIKitCore 0x00007ff805d13f4b -[UIWindow _rotateWindowToOrientation:updateStatusBar:duration:skipCallbacks:] + 2044
23 UIKitCore 0x00007ff805d14509 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 642
24 UIKitCore 0x00007ff805d0fcf3 -[UIWindow _internal_setRotatableViewOrientation:updateStatusBar:duration:force:] + 113
25 UIKitCore 0x00007ff805d12120 __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 214
26 UIKitCore 0x00007ff805d11dc2 -[UIWindow _updateToInterfaceOrientation:duration:force:] + 1166
27 UIKitCore 0x00007ff804fe4967 -[_UIScenefbsSceneBasedMetricsCalculator _updateMetricsOnWindows:animated:] + 1822
28 UIKitCore 0x00007ff806017c7e -[UIWindowScene _computeMetricsForWindows:animated:] + 89
29 UIKitCore 0x00007ff806016c85 __55-[UIWindowScene _computeMetrics:withTransitionContext:]_block_invoke + 133
30 UIKitCore 0x00007ff806016e16 -[UIWindowScene _computeTraitCollectionAndCoordinateSpaceForcingDelegateCallback:withAction:] + 360
31 UIKitCore 0x00007ff806016bfa -[UIWindowScene _computeMetrics:withTransitionContext:] + 75
32 UIKitCore 0x00007ff806013123 -[UIWindowScene _computeMetricsAndCrossFadeInLiveResize:withTransitionContext:] + 231
33 UIKitCore 0x00007ff806397e43 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 580
34 UIKitCore 0x00007ff8063980f8 +[UIView(UIViewAnimationWithBlocks) _animateWithDuration:delay:options:factory:animations:completion:] + 20
35 UIKitCore 0x00007ff80558439c +[BSAnimationSettings(UIKit) tryAnimatingWithSettings:fromCurrentState:actions:completion:] + 633
36 UIKitCore 0x00007ff8056f64c3 _UISceneSettingsDiffActionPerformChangesWithTransitionContextAndCompletion + 261
37 UIKitCore 0x00007ff804feb651 -[_UIWindowSceneGeometrySettingsDiffAction _updateSceneGeometryWithSettingObserverContext:windowScene:transitionContext:] + 962
38 UIKitCore 0x00007ff804feb1c9 -[_UIWindowSceneGeometrySettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:] + 1507
39 UIKitCore 0x00007ff804dc04db __64-[UIScene scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke.613 + 877
40 UIKitCore 0x00007ff804dbee90 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:] + 245
41 UIKitCore 0x00007ff804dc0043 -[UIScene scene:didUpdateWithDiff:transitionContext:completion:] + 252
42 UIKitCore 0x00007ff8055b9d76 -[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:] + 466
43 FrontBoardServices 0x00007ff807a18b99 -[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:] + 850
44 FrontBoardServices 0x00007ff807a4caa4 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2 + 149
45 FrontBoardServices 0x00007ff807a26a78 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 213
46 FrontBoardServices 0x00007ff807a4c9dc __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke + 381
47 libdispatch.dylib 0x000000011441758f _dispatch_client_callout + 8
48 libdispatch.dylib 0x000000011441af65 _dispatch_block_invoke_direct + 507
49 FrontBoardServices 0x00007ff807a7635f __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
50 FrontBoardServices 0x00007ff807a76239 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 188
51 FrontBoardServices 0x00007ff807a76387 -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 19
52 CoreFoundation 0x00007ff800429fb3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
53 CoreFoundation 0x00007ff800429ef5 __CFRunLoopDoSource0 + 157
54 CoreFoundation 0x00007ff8004296f2 __CFRunLoopDoSources0 + 215
55 CoreFoundation 0x00007ff800423e27 __CFRunLoopRun + 919
56 CoreFoundation 0x00007ff8004236ad CFRunLoopRunSpecific + 557
57 GraphicsServices 0x00007ff8103da08f GSEventRunModal + 137
58 UIKitCore 0x00007ff805cc0ad1 -[UIApplication _run] + 972
59 UIKitCore 0x00007ff805cc5551 UIApplicationMain + 123
60 UIKitCore 0x00007ff804d3f563 __swift_destroy_boxed_opaque_existential_1Tm + 10307
61 Love2DGameMaker 0x000000010e96537b $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 123
62 Love2DGameMaker 0x000000010e9652f7 $s15Love2DGameMaker11AppDelegateC5$mainyyFZ + 39
63 Love2DGameMaker 0x000000010e965448 main + 24
64 dyld 0x000000011132b3e0 start_sim + 10
65 ??? 0x000000011b37e366 0x0 + 4751614822
```
the third:
```objc
0 Love2DGameMaker 0x000000010e8d5398 $s15Love2DGameMaker27SimulatorRootViewControllerC18viewWillTransition2to4withySo6CGSizeV_So06UIViewgJ11Coordinator_ptFySo0ngjO7Context_pcfU2_ + 376
1 Love2DGameMaker 0x000000010e8d51a9 $sSo44UIViewControllerTransitionCoordinatorContext_pIegg_SoAA_pIeyBy_TR + 57
2 UIKitCore 0x00007ff805308490 -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] + 145
3 UIKitCore 0x00007ff80530384a -[_UIViewControllerTransitionContext _runAlongsideCompletions] + 126
4 UIKitCore 0x00007ff805303654 -[_UIViewControllerTransitionContext completeTransition:] + 117
5 UIKitCore 0x00007ff805325f32 __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke_2.183 + 26
6 UIKitCore 0x00007ff80639c5cd +[UIView _performBlockDelayingTriggeringResponderEvents:forScene:] + 203
7 UIKitCore 0x00007ff805325ed4 __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke.182 + 148
8 UIKitCore 0x00007ff8063974e0 __UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK__ + 15
9 UIKitCore 0x00007ff8063977e9 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 775
10 UIKitCore 0x00007ff806362ca8 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 279
11 UIKitCore 0x00007ff806363257 -[UIViewAnimationState animationDidStop:finished:] + 276
12 QuartzCore 0x00007ff80b19bd9a _ZL23run_animation_callbacksPv + 186
13 libdispatch.dylib 0x000000011441758f _dispatch_client_callout + 8
14 libdispatch.dylib 0x00000001144273ee _dispatch_main_queue_drain + 1362
15 libdispatch.dylib 0x0000000114426e8e _dispatch_main_queue_callback_4CF + 31
16 CoreFoundation 0x00007ff800429af4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
17 CoreFoundation 0x00007ff80042442f __CFRunLoopRun + 2463
18 CoreFoundation 0x00007ff8004236ad CFRunLoopRunSpecific + 557
19 GraphicsServices 0x00007ff8103da08f GSEventRunModal + 137
20 UIKitCore 0x00007ff805cc0ad1 -[UIApplication _run] + 972
21 UIKitCore 0x00007ff805cc5551 UIApplicationMain + 123
22 UIKitCore 0x00007ff804d3f563 __swift_destroy_boxed_opaque_existential_1Tm + 10307
23 Love2DGameMaker 0x000000010e96537b $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 123
24 Love2DGameMaker 0x000000010e9652f7 $s15Love2DGameMaker11AppDelegateC5$mainyyFZ + 39
25 Love2DGameMaker 0x000000010e965448 main + 24
26 dyld 0x000000011132b3e0 start_sim + 10
27 ??? 0x000000011b37e366 0x0 + 4751614822
```
Bad Case:
When the issue occurs, I find out the rotation animation does not complete.
This is some code of rootviewcontroller:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
NSLog(@"%s, size: %@", __PRETTY_FUNCTION__, NSStringFromCGSize(size));
NSLog(@"%@", NSThread.callStackSymbols);
NSLog(@"%@", self.view);
NSLog(@"%@", self.view.subviews);
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
NSLog(@"animation block");
fprintf(stderr, "stderr animation block\n");
fprintf(stdout, "stdout animation block\n");
NSLog(@"%@", NSThread.callStackSymbols);
NSLog(@"animation block SDL_uikitviewcontroller runloop mode: %@", NSRunLoop.currentRunLoop.currentMode);
NSLog(@"%@", self.view);
NSLog(@"%@", self.view.subviews);
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
NSLog(@"completion block, isCancelled: %@", context.isCancelled ? @"YES" : @"NO");
fprintf(stderr, "stderr animation completion block\n");
fprintf(stdout, "stdout animation completion block\n");
NSLog(@"%@", NSThread.callStackSymbols);
NSLog(@"animation complete block SDL_uikitviewcontroller runloop mode: %@", NSRunLoop.currentRunLoop.currentMode);
}];
[coordinator notifyWhenInteractionChangesUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
NSLog(@"%s", __PRETTY_FUNCTION__);
}];
}
I guess this issue is similar to another common issue: UINavigationController push/pop viewcontroller when previous push/pop animation is running, or showing a UIAlertController when viewcontroller is being pushing/popping
They all have the same result, the app become unresponsive to touch events, but they can respond to other events(I did some test, the app is still running, not in a deadlock state, it just can not respond to touch events)
I guess the root cause of this issue is the animations conflict, or the view hierarchy changed when animating, so the animation states and the view hierarchy were messed up.
But I don't know how to fix it.
I have a workaround, but it has side effect.