我正在创建一个弹出菜单。它有一个在显示之前根据呈现的视图控制器的视图大小进行UIPresentationController
计算。frameOfPresentedViewInContainerView
- 呈现的视图控制器由固定高度的外部(导航)视图控制器嵌入一些动态高度的内部(内容)视图控制器组成;
- 内部视图控制器,在引擎盖下,
UIStackView
包裹在UIScrollView
; - 在计算内部视图控制器的大小之前,我正在调用
layoutIfNeeded()
它。
该问题仅发生在带有缺口的设备上(我责怪 safeAreaLayout),并且仅发生在基于 UIStackView 的内部视图控制器上。当layoutIfNeeded()
在呈现的控制器上调用时(例如,当显示方向改变、内容大小改变或第二次呈现时)UIKitCore 进入无限循环调用-[UIView layoutGuides]
。它不会使应用程序崩溃,而是使用 100% 的主线程并冻结 UI(有时整个手机都需要硬重置),每秒消耗大约 10Mb 的内存。
我能够通过在frameOfPresentedViewInContainerView
. 这听起来像是一个糟糕的修复,所以我试图更好地理解这个问题。
如果对 UIKit 有深入了解的人可以为我指出如何调试/调查问题的更好策略,我会很高兴。
更新
由于安全区域,似乎UIScrollView
很难定位内容。UIKitCore 不断重复这 5 行:
- [UIScrollView _layoutGuideOfType:createIfNecessary:]
- [NSISEngine(_UILayoutEngineStatistics)_UIKitPerformPendingChangeNotifications]
- [UIView layoutGuides]
- [_UIScrollViewScrollIndicator _layoutFillViewAnimated:]
- [UIView(AdditionalLayoutSupport) nsli_lowerAttribute:intoExpression:withCoefficient:forConstraint:onBehalfOfLayoutGuide:]
我也有
runtime: Layout Issues: Scrollable content size is ambiguous for UIScrollView.