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
UIStackViewwrapped 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.
I was able to fix my issue by specifically attaching UIScrollView to the bottom of safeAreaLayoutGuide.