调用 [UIViewController updateViewConstraints] 后 UITableView contentSize 为零

Posted

技术标签:

【中文标题】调用 [UIViewController updateViewConstraints] 后 UITableView contentSize 为零【英文标题】:UITableView contentSize zero after [UIViewController updateViewConstraints] is called 【发布时间】:2014-09-03 22:53:11 【问题描述】:

在将项目转换为使用自动布局的过程中,我正在处理一个问题,即 UITableViewcontentSize 最初设置正确,但在父 UITableViewController-updateViewConstraints 之后被调用时,contentSize 为零。

App[36457:60b] -- viewWillAppear in (KRTestTableViewController) 被调用! App[36457:60b] -- viewWillLayoutSubviews (KRTestTableViewController): 内容大小 = (320.0, 611.0), inset=(64.0, 93.0), offset=(-64.0), layout guides=(64.0, 93.0) App[36457:60b] -- viewDidLayoutSubviews (KRTestTableViewController): 内容大小 = (320.0, 611.0), inset=(64.0, 93.0), offset=(-64.0), layout guides=(64.0, 93.0) App[36457:60b] **** updateConstraints 调用(KRTestTableViewCell) App[36457:60b] **** updateViewConstraints 在 (KRTestTableViewController) 中调用。内容大小高度=(611.0), contentOffset = -64.0, inset=(64.0, 93.0) App[36457:60b] 在调用 [super updateViewConstraints] 之前,KRTestTableViewController.view.needsUpdateConstraints = 1 App[36457:60b] 调用 [super updateViewConstraints] 后,KRTestTableViewController.view.needsUpdateConstraints = 0 App[36457:60b] -- viewWillLayoutSubviews (KRTestTableViewController): 内容大小 = (0.0, 0.0), inset=(64.0, 93.0), offset=(-64.0), layout guides=(64.0, 93.0) App[36457:60b] -- viewDidLayoutSubviews (KRTestTableViewController): 内容大小 = (0.0, 0.0), inset=(64.0, 93.0), offset=(-64.0), layout guides=(64.0, 93.0) App[36457:60b] -- viewDidAppear in (KRTestTableViewController) 被调用!

我已将问题缩小到在更新约束后将内容大小设置为零。 关于可能导致此问题或如何解决此问题的任何想法? 这是正常的预期顺序:查看布局,然后更新约束,再次查看布局?

【问题讨论】:

由于未知的原因,在 -viewDidAppear 中调用 [tableView begin/endUpdates] 或空的 [tableView reloadRowsAtIndexPaths:nil ...] 会在视图控制器中触发 -viewWill/DidLayoutSubviews,然后生成正确的 -contentSize。把它放在-viewWillAppear 中不会。 【参考方案1】:

找到根本原因! topLayoutGuideUITableViewController 存在一个错误,如果您调用topLayoutGuideUITableViewcontentSize 将设置为零!数小时的 bug 搜寻是由一个非常不必要的调试日志语句输出的值 topLayoutGuide =_+

我之前关于调用reloadRowsAtIndexPaths:nil ... 修复contentSize 的评论仍然纠正了contentSize。我已将它(带有零校验)放在viewDidLayoutSubviews 中,以防出现对topLayoutGuide 的需求。

在此处查看相同的问题:Calling topLayoutGuide breaks scrolling altogether?

【讨论】:

以上是关于调用 [UIViewController updateViewConstraints] 后 UITableView contentSize 为零的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 UIViewController 初始化程序从未被调用?

UIViewController中各方法调用顺序及功能详解

调用 UIViewController 类的非静态函数

通过 addSubview 添加后,在父 UIViewController 中调用方法

是否应该明确调用 willMoveToParentViewController:(UIViewController *)parent & didMoveToParentViewControll

如何从 UIView 子类调用 UIViewController?