SwiftUI Popover Crash During Resizing in Stage Manager

SwiftUI Popover Crash on iPad During Resizing in Stage Manager with Exception.

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Trying to layout popover in the delegate callback popoverPresentationController:willRepositionPopoverToRect:inView: will lead to recursion. Do not force the popover's container view or an ancestor to layout in this callback.'

(Occurred from iPadOS 18.1)

struct ContentView: View {
@State var showPopover: Bool = false
var body: some View {
VStack {
Text("Hello, world!")
Button(action: {
showPopover = true
}, label: {
Text("Open Popover")
})
}
.padding()
.popover(isPresented: $showPopover, attachmentAnchor: .point(.trailing), content: {
VStack {
Text("Popover Content")
}
})
}
}

+1 Seeing the exact same stacktrace in SwiftUI since our app launched. Our app is 100% SwiftUI. However, I've never been able to figure out why and when the crashes happens. This is currently our NO.1 source of crashes.

Fatal Exception: NSInternalInconsistencyException
Trying to layout popover in the delegate callback popoverPresentationController:willRepositionPopoverToRect:inView: will lead to recursion. Do not force the popover's container view or an ancestor to layout in this callback.
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x827cc __exceptionPreprocess
1 libobjc.A.dylib 0x172e4 objc_exception_throw
2 Foundation 0x80f8d8 _userInfoForFileAndLine
3 UIKitCore 0xa617e8 -[UIPopoverPresentationController _sendDelegateWillRepositionToRect]
4 UIKitCore 0xa61fd0 -[UIPopoverPresentationController containerViewWillLayoutSubviews]
5 UIKitCore 0xd414 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
6 QuartzCore 0x78c28 CA::Layer::layout_if_needed(CA::Transaction*)
7 UIKitCore 0x50138 -[UIView(Hierarchy) layoutBelowIfNeeded]
8 SwiftUI 0xc799f4 specialized PopoverPresentationDelegate.updateAnchor(_:presentationController:)
9 SwiftUI 0xc72b08 closure #1 in UIKitInspectorV3Bridge.updateAnchor()
10 SwiftUICore 0x1f1308 partial apply for thunk for @escaping @callee_guaranteed () -> ()
11 SwiftUICore 0x4a5d3c static Update.dispatchActions()
12 SwiftUICore 0x4a520c static Update.end()
13 SwiftUICore 0x4a5fd8 closure #1 in static Update.ensure<A>(_:)
14 SwiftUICore 0x4a4dd4 static Update.ensure<A>(_:)
15 SwiftUI 0xc75790 UIKitInspectorV3Bridge.popoverSource(for:)
16 SwiftUI 0xc7a84c specialized PopoverPresentationDelegate.popoverPresentationController(_:willRepositionPopoverTo:in:)
17 SwiftUI 0xc75af0 @objc PopoverPresentationDelegate.popoverPresentationController(_:willRepositionPopoverTo:in:)
18 UIKitCore 0xa6185c -[UIPopoverPresentationController _sendDelegateWillRepositionToRect]
19 UIKitCore 0xa61fd0 -[UIPopoverPresentationController containerViewWillLayoutSubviews]
20 UIKitCore 0xd414 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
21 QuartzCore 0x78c28 CA::Layer::layout_if_needed(CA::Transaction*)
22 UIKitCore 0x50138 -[UIView(Hierarchy) layoutBelowIfNeeded]
23 UIKitCore 0x546cc -[UIWindowScene _enumerateWindowsIncludingInternalWindows:onlyVisibleWindows:asCopy:stopped:withBlock:]
24 UIKitCore 0x82b258 ___UIWindowHostingScenePerformUpdateWithEffectiveSettings_block_invoke_2
25 UIKitCore 0x38c0ac +[UIViewController _performWithoutDeferringTransitionsAllowingAnimation:actions:]
26 UIKitCore 0x82b160 ___UIWindowHostingScenePerformUpdateWithEffectiveSettings_block_invoke
27 UIKitCore 0x7ff30 +[UIView(Animation) performWithoutAnimation:]
28 UIKitCore 0x82a20c _UIWindowHostingScenePerformUpdateWithEffectiveSettings
29 UIKitCore 0x82a2c8 -[UIScene _enableOverrideSettingsForActions:]
30 UIKitCore 0x82a490 -[UIScene _performSystemSnapshotWithActions:]
31 UIKitCore 0x114428c -[UIApplication _performSnapshotsWithAction:forScene:completion:]
32 UIKitCore 0x1607954 __98-[_UISceneSnapshotBSActionsHandler _respondToActions:forFBSScene:inUIScene:fromTransitionContext:]_block_invoke_3
33 UIKitCore 0x16077d0 __98-[_UISceneSnapshotBSActionsHandler _respondToActions:forFBSScene:inUIScene:fromTransitionContext:]_block_invoke_2
34 UIKitCore 0x216190 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:]
35 UIKitCore 0x2d5824 -[UIScene scene:didUpdateWithDiff:transitionContext:completion:]
36 UIKitCore 0x2d5404 -[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:]
37 FrontBoardServices 0x371bc __76-[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:]_block_invoke.193
38 FrontBoardServices 0x36d6c -[FBSScene _callOutQueue_coalesceClientSettingsUpdates:]
39 FrontBoardServices 0x63c8 -[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:]
40 FrontBoardServices 0x14db8 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2
41 FrontBoardServices 0x14c44 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:]
42 FrontBoardServices 0x19114 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke
43 libdispatch.dylib 0x40d0 _dispatch_client_callout
44 libdispatch.dylib 0x7b14 _dispatch_block_invoke_direct
45 FrontBoardServices 0x16300 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__
46 FrontBoardServices 0x16280 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible]
47 FrontBoardServices 0x16158 -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource]
48 CoreFoundation 0x56328 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
49 CoreFoundation 0x562bc __CFRunLoopDoSource0
50 CoreFoundation 0x53dc0 __CFRunLoopDoSources0
51 CoreFoundation 0x52fbc __CFRunLoopRun
52 CoreFoundation 0x52830 CFRunLoopRunSpecific
53 GraphicsServices 0x11c4 GSEventRunModal
54 UIKitCore 0x3d2eb0 -[UIApplication _run]
55 UIKitCore 0x4815b4 UIApplicationMain
56 SwiftUI 0x101f98 closure #1 in KitRendererCommon(_:)
57 SwiftUI 0xe2664 runApp<A>(_:)
58 SwiftUI 0xe5490 static App.main()
59 Notewise 0x8839c4 main (NotewiseApp.swift)
60 ??? 0x1b1df6ec8 (Missing)

We're seeing the same thing in a SwiftUI portion of our app. It seems this started showing up with iOS 18.1.0. Unfortunately, we haven't been able to reproduce it.

0 CoreFoundation 0x827cc __exceptionPreprocess
1 libobjc.A.dylib 0x172e4 objc_exception_throw
2 Foundation 0x80f8d8 _userInfoForFileAndLine
3 UIKitCore 0xa617e8 -[UIPopoverPresentationController _sendDelegateWillRepositionToRect]
4 UIKitCore 0xa61fd0 -[UIPopoverPresentationController containerViewWillLayoutSubviews]
5 UIKitCore 0xd414 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
6 QuartzCore 0x78c28 CA::Layer::layout_if_needed(CA::Transaction*)
7 UIKitCore 0x50138 -[UIView(Hierarchy) layoutBelowIfNeeded]
8 SwiftUI 0xc799f4 specialized PopoverPresentationDelegate.updateAnchor(_:presentationController:)
9 SwiftUI 0xc72b08 closure #1 in UIKitInspectorV3Bridge.updateAnchor()
10 SwiftUICore 0x1f1308 partial apply for thunk for @escaping @callee_guaranteed () -> ()
11 SwiftUICore 0x4a5d3c static Update.dispatchActions()
12 SwiftUICore 0x4a520c static Update.end()
13 SwiftUICore 0x4a5fd8 closure #1 in static Update.ensure<A>(_:)
14 SwiftUICore 0x4a4dd4 static Update.ensure<A>(_:)
15 SwiftUI 0xc75790 UIKitInspectorV3Bridge.popoverSource(for:)
16 SwiftUI 0xc7a84c specialized PopoverPresentationDelegate.popoverPresentationController(_:willRepositionPopoverTo:in:)
17 SwiftUI 0xc75af0 @objc PopoverPresentationDelegate.popoverPresentationController(_:willRepositionPopoverTo:in:)
18 UIKitCore 0xa6185c -[UIPopoverPresentationController _sendDelegateWillRepositionToRect]
19 UIKitCore 0xa61b10 __86-[UIPopoverPresentationController viewWillTransitionToSize:withTransitionCoordinator:]_block_invoke
20 UIKitCore 0xb1c3ac __UIVIEWCONTROLLERTRANSITIONCOORDINATOR_IS_EXECUTING_ALONGSIDE_ANIMATION_BLOCK__
21 UIKitCore 0x2e3648 -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:]
22 UIKitCore 0x2e33d0 -[_UIViewControllerTransitionContext _runAlongsideCompletions]
23 UIKitCore 0x2e31a0 -[_UIViewControllerTransitionContext completeTransition:]
24 UIKitCore 0x1762b8 __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke_5
25 UIKitCore 0x175b78 +[UIView _performBlockDelayingTriggeringResponderEvents:forScene:]
26 UIKitCore 0x2e40f8 __58-[_UIWindowRotationAnimationController animateTransition:]_block_invoke_4
27 UIKitCore 0x7bfb0 __UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK__
28 UIKitCore 0x12ab88 -[UIViewAnimationBlockDelegate _sendDeferredCompletion:]
29 libdispatch.dylib 0x2370 _dispatch_call_block_and_release
30 libdispatch.dylib 0x40d0 _dispatch_client_callout
31 libdispatch.dylib 0x129e0 _dispatch_main_queue_drain
32 libdispatch.dylib 0x125fc _dispatch_main_queue_callback_4CF
33 CoreFoundation 0x56204 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
34 CoreFoundation 0x53440 __CFRunLoopRun
35 CoreFoundation 0x52830 CFRunLoopRunSpecific
36 GraphicsServices 0x11c4 GSEventRunModal
37 UIKitCore 0x3d2eb0 -[UIApplication _run]
38 UIKitCore 0x4815b4 UIApplicationMain
39 Takedown 0x18cbac main + 43 (tWrestlingAppDelegate.swift:43)
40 ??? 0x1abda6ec8 (Missing)

+1 Seeing the exact same issue

The issue happens only on iPadOS 18. To reproduce the user has to open the popover on the iPad and then switch the app to the background (keeping the popover visible). Then the crash occurs.

See FB16077587 for a sample project with instructions.

I have the same crash when I simply want to rotate my iPad. Is there some way to detect rotation in SwiftUI and dismiss popover manually?

+1 We're seeing the same stack trace.

iPadOS 18+, all SwiftUI, and according to our logs, it happens when the app is backgrounded, but we haven't been able to reproduce it yet.

Same issue here. Easily reproducible by running an iPad App on Mac (Designed for iPad) and resizing the window while any popover view is displayed.

As a workaround, I have found that closing the popover on scene change stops the crash:

@Environment(\.scenePhase) var scenePhase
HStack {
...
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .background {
showPopover = false
}
}

Subscribing to this issue. I have the same crash when rotating while any popover is visible.

It happens both on iPhone (using .presentationCompactAdaptation(.popover) on child view) & iPad after a few rotations

SwiftUI Popover Crash During Resizing in Stage Manager
 
 
Q