viewDidLayoutSubviews 陷入空白方法的无限循环
viewDidLayoutSubviews stuck in infinite loop for blank method
我有一个在 UIStoryboard 中使用 UITableView 设置的视图控制器。 UITableView 在所有四个边上都被限制在控制器的 SafeArea 中。
这个问题貌似以前有人问过,但是每次找到问题都是因为viewDidLayoutSubviews发生了变化,导致出现了循环。我有一个 blank 实现 viewDidLayoutSubviews 和基本的 UITableViewCells(没有笔尖)。然而在 iOS 11、Xcode 9.2 中,向上轻弹 tableview 会导致 viewDidLayoutSubviews 在无限循环中被调用。这是我的实现:
- (void)viewDidLayoutSubviews {
NSLog(@"viewDidLayoutSubviews");
[super viewDidLayoutSubviews];
}
我一辈子都弄不明白这是怎么回事。
编辑:控制器有一个 NavigationController 并且是嵌入在 BannerViewController 中的 UISplitViewController 的主控制器(来自 iAdSuite 示例)。
编辑:这发生在 iOS 11(直到 11.2)在模拟器的所有设备上。不会发生 iOS 10.3。 viewDidLayoutSubviews
在 iOS 10.3 中甚至没有被调用。当我简单地使用 Nav Controller 和 UIViewController/TableView 代替 UISplitViewController/BannerViewController 时,我得到了相同的结果。所以似乎问题没有在那里介绍,而是来自 iOS 11.
中发生的事情
编辑:所以这很奇怪 - 似乎只有在为导航控制器选择大标题时才会发生!
if (@available(iOS 11.0, *)) {
self.navigationController.navigationBar.prefersLargeTitles = YES;
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
}
编辑:这个问题很容易重现。我下载了 Apple 的 iAd Suite 示例代码,并使用了 SplitNavigationController 项目。我更新了 iOS 11 的项目,包括更新故事板以使用安全区域布局指南。我将 MasterViewController 从 UITableViewController 更改为带有 UITableView 的 UIViewController,我将其限制在故事板中的安全区域布局指南中。我在 MasterViewController 中添加了 prefersLargeTitles 和 largeTitleDisplayMode。我在 viewDidLayoutSubviews 方法中添加了一个 NSLog 语句,因此可以很容易地观察到这种行为。我认为这是 iOS 11 的一个真正的问题,我会尽力查明它,如果其他人可以提供任何想法或建议,我也将不胜感激。
编辑:matt 能够在 GitHub 项目中重现此问题并 post,可在以下 link 中找到(感谢 matt!):InfiniteLayoutSubviewsBug
编辑 这绝对是 iOS 11 至至少 iOS 11.2 中的错误,但在 iOS 12 中错误不再存在存在。
您似乎发现了一个错误。我能够在一个最小的示例项目中重现该问题,我已将其发布在 GitHub 此处:
https://github.com/mattneub/InfiniteLayoutSubviewsBug
下载项目并运行。您会看到一个包含三行的简单 table。向上滚动 table 视图 然后放开。观看控制台。我们收到对 viewDidLayoutSubviews
的重复调用,每 1/60 秒一次,永远如此。
请注意,这是 而不是 由我们代码中的递归布局循环引起的。我的示例甚至没有调用 super
。它所做的只是记录。这是 运行时间本身 永远重复调用 viewDidLayoutSubviews
。发生这种情况时没有我们的代码(print
除外)运行。
其他观察:
正如您正确观察到的那样,如果您更改示例以使导航栏不使用大标题,问题就会消失。
如果您更改示例,使 table 视图不使用自动布局定位,问题就会消失。
如果您更改示例(更详细地)以便视图控制器是 UITableViewController 的子类,问题就会消失;我们收到一些重复调用 viewDidLayoutSubviews
但不是永远,只是在滚动时。
我有一个在 UIStoryboard 中使用 UITableView 设置的视图控制器。 UITableView 在所有四个边上都被限制在控制器的 SafeArea 中。
这个问题貌似以前有人问过,但是每次找到问题都是因为viewDidLayoutSubviews发生了变化,导致出现了循环。我有一个 blank 实现 viewDidLayoutSubviews 和基本的 UITableViewCells(没有笔尖)。然而在 iOS 11、Xcode 9.2 中,向上轻弹 tableview 会导致 viewDidLayoutSubviews 在无限循环中被调用。这是我的实现:
- (void)viewDidLayoutSubviews {
NSLog(@"viewDidLayoutSubviews");
[super viewDidLayoutSubviews];
}
我一辈子都弄不明白这是怎么回事。
编辑:控制器有一个 NavigationController 并且是嵌入在 BannerViewController 中的 UISplitViewController 的主控制器(来自 iAdSuite 示例)。
编辑:这发生在 iOS 11(直到 11.2)在模拟器的所有设备上。不会发生 iOS 10.3。 viewDidLayoutSubviews
在 iOS 10.3 中甚至没有被调用。当我简单地使用 Nav Controller 和 UIViewController/TableView 代替 UISplitViewController/BannerViewController 时,我得到了相同的结果。所以似乎问题没有在那里介绍,而是来自 iOS 11.
编辑:所以这很奇怪 - 似乎只有在为导航控制器选择大标题时才会发生!
if (@available(iOS 11.0, *)) {
self.navigationController.navigationBar.prefersLargeTitles = YES;
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
}
编辑:这个问题很容易重现。我下载了 Apple 的 iAd Suite 示例代码,并使用了 SplitNavigationController 项目。我更新了 iOS 11 的项目,包括更新故事板以使用安全区域布局指南。我将 MasterViewController 从 UITableViewController 更改为带有 UITableView 的 UIViewController,我将其限制在故事板中的安全区域布局指南中。我在 MasterViewController 中添加了 prefersLargeTitles 和 largeTitleDisplayMode。我在 viewDidLayoutSubviews 方法中添加了一个 NSLog 语句,因此可以很容易地观察到这种行为。我认为这是 iOS 11 的一个真正的问题,我会尽力查明它,如果其他人可以提供任何想法或建议,我也将不胜感激。
编辑:matt 能够在 GitHub 项目中重现此问题并 post,可在以下 link 中找到(感谢 matt!):InfiniteLayoutSubviewsBug
编辑 这绝对是 iOS 11 至至少 iOS 11.2 中的错误,但在 iOS 12 中错误不再存在存在。
您似乎发现了一个错误。我能够在一个最小的示例项目中重现该问题,我已将其发布在 GitHub 此处:
https://github.com/mattneub/InfiniteLayoutSubviewsBug
下载项目并运行。您会看到一个包含三行的简单 table。向上滚动 table 视图 然后放开。观看控制台。我们收到对 viewDidLayoutSubviews
的重复调用,每 1/60 秒一次,永远如此。
请注意,这是 而不是 由我们代码中的递归布局循环引起的。我的示例甚至没有调用 super
。它所做的只是记录。这是 运行时间本身 永远重复调用 viewDidLayoutSubviews
。发生这种情况时没有我们的代码(print
除外)运行。
其他观察:
正如您正确观察到的那样,如果您更改示例以使导航栏不使用大标题,问题就会消失。
如果您更改示例,使 table 视图不使用自动布局定位,问题就会消失。
如果您更改示例(更详细地)以便视图控制器是 UITableViewController 的子类,问题就会消失;我们收到一些重复调用
viewDidLayoutSubviews
但不是永远,只是在滚动时。