我遇到的问题是topLayoutGuide.length
(来自XIB)UIViewController
在viewWillAppear
之后设置,我不知道如何挂钩{{1}的更改最初设置表视图的contentOffset。
代码在topLayoutGuide.length
内以模态方式显示UIViewController
:
UINavigationController
关于let viewController = UIViewController(nibName: "ViewController", bundle: nil)
let navigationController = UINavigationController(rootViewController: viewController)
present(navigationController, animated: true, completion: nil)
topLayoutGuide.length
现在我在视图控制器中使用bool标志只在Init view controller
-[UIViewController topLayoutGuide]: guide not available before the view controller's view is loaded
willMove toParentViewController - top layout guide nan
Init navigation controller and pass view controller as root vc
Present navigation controller modally
viewDidLoad - top layout guide 0.0
viewWillAppear - top layout guide 0.0
viewWillLayoutSubviews - top layout guide 64.0
viewDidLayoutSubviews - top layout guide 64.0
viewWillLayoutSubviews - top layout guide 64.0
viewDidLayoutSubviews - top layout guide 64.0
viewDidAppear - top layout guide 64.0
didMove toParentViewController - top layout guide 64.0
viewWillLayoutSubviews - top layout guide 64.0
viewDidLayoutSubviews - top layout guide 64.0
中设置一次contentoffset,即使该方法被多次调用。
还有更优雅的解决方案吗?
答案 0 :(得分:3)
documentation for the topLayoutGuide
明确声明:
在
finally()
方法的实现中查询此属性。
从您自己的检查来看,获得viewDidLayoutSubviews()
实际长度的最早点是topLayoutGuide
方法。但是,我不会依赖于此,并按照文档建议的那样在viewWillLayoutSubviews()
中执行此操作。
...布局指南是依赖于任何容器视图控制器布局的对象。在屏幕上需要时,这些视图会被懒散地布置。因此,当您将viewDidLayoutSubviews()
添加到viewController
作为其根视图控制器时,它尚未布局。
当您展示navigationViewController
时,会发生布局。此时,将加载两个视图控制器的视图(→navigationController
,viewDidLoad()
),然后触发布局传递。首先,列出viewWillAppear()
的视图(布局流程:superview→subview)。导航栏的框架设置为64像素的高度。现在可以设置navigationViewController
的{{1}}。最后列出了viewController
的视图(→topLayoutGuide
,viewController
)。
根据布局指南的长度进行某些初始布局调整的唯一方法是您自己建议的方法:
在您最初设置为viewWillLayoutSubviews()
的视图控制器中有一个布尔属性:
viewDidLayoutSubviews()
在true
内检查该属性,并仅在var isInitialLayoutPass: Bool = true
时执行初始布局:
viewDidLayoutSubviews()
在true
内,将属性设置为func viewDidLayoutSubviews() {
if isInitialLayoutPass {
tableView.contentOffset = CGPoint(x: 0, y: topLayoutGuide.length)
}
}
,表示初始布局已完成:
viewDidAppear()
我知道它仍然感觉有点hacky但我担心这是唯一的方法(我能想到的),除非你想使用键值观察(KVO)在我看来,它并没有让它更整洁。