I am creating a popup menu. It has a UIPresentationController
that calculates frameOfPresentedViewInContainerView
based on presented view controller's view size before showing it.
- Presented view controllers consist of the fixed height outer (navigation) view controller embedding some dynamic height inner (content) view controller;
- Inner view controllers, under the hood, have
UIStackView
wrapped in aUIScrollView
; - Before calculating size of inner view controller I am calling
layoutIfNeeded()
on it.
The problem occurred only on devices with the notch (I blame safeAreaLayout) and only with a UIStackView-based inner view controllers. When layoutIfNeeded()
called on presented controller (e.x. when display orientation change, content size change, or presented second time) UIKitCore goes into an infinite loop calling -[UIView layoutGuides]
. It doesn't crash the app, but use 100% of the main thread and freezes the UI(sometimes whole phone to the point you need make a hard reset), consuming about 10Mb of memory every second.
I was able to fix it by adding 1 extra point to a calculated height of the frameOfPresentedViewInContainerView
. This sounds like an awful fix, so I am trying to better understand the problem.
I would be glad if someone with a deep understanding of UIKit could point me to a better strategy on how to debug/investigate the issue.
UPDATE
Seems like UIScrollView
having hard time positioning content due to a safeArea. UIKitCore keeps repeating those 5 lines:
- [UIScrollView _layoutGuideOfType:createIfNecessary:]
- [NSISEngine(_UILayoutEngineStatistics)_UIKitPerformPendingChangeNotifications]
- [UIView layoutGuides]
- [_UIScrollViewScrollIndicator _layoutFillViewAnimated:]
- [UIView(AdditionalLayoutSupport) nsli_lowerAttribute:intoExpression:withCoefficient:forConstraint:onBehalfOfLayoutGuide:]
I also have
runtime: Layout Issues: Scrollable content size is ambiguous for UIScrollView.