相同的视图控制器显示不同
Identical View Controllers Displaying Differently
我有两个子视图控制器,据我所知它们是相同的,但是其中一个出现意外。
这两个子视图控制器称为 MenuLoggedInViewController
和 MenuLoggedOutViewController
。他们的容器视图控制器具有以下代码:
override func viewDidLoad() {
super.viewDidLoad()
// i comment out one of these two lines to produce the different results:
self.masterView = MenuLoggedOutViewController(nibName: "MenuLoggedOutViewController", bundle: nil)
// self.masterView = MenuLoggedInViewController(nibName: "MenuLoggedInViewController", bundle: nil)
self.detailView = RootViewController(nibName: "RootViewController", bundle: nil)
self.masterViewFrame = CGRectMake(0, 0, self.view.frame.width, 50)
self.detailViewFrame = CGRectMake(0, 50, self.view.frame.width, self.view.frame.height - 50)
self.addChildViewController(masterView!)
self.addChildViewController(detailView!)
self.view.addSubview(masterView!.view)
self.view.addSubview(detailView!.view)
masterView!.view.frame = masterViewFrame
// masterView!.view.bounds = masterViewFrame // - i tried this and it made no difference
detailView!.view.frame = detailViewFrame
}
MenuLoggedInViewController
和 MenuLoggedOutViewController
在它们的 swift 文件中有几乎相同的模板代码:
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
除了更改背景颜色外,我没有触及 .xib
文件。在完成 .xib
文件的设置后,它们 似乎 都是一样的。如果可以的话,我不会靠近故事板,所以我对它不太熟悉。但是我花了很长时间仔细检查两个 .xib
文件的所有值,除了背景颜色之外,我可以检测到它们之间没有区别。
如您所见,黑色 MenuLoggedInViewController
紧贴下方的白色视图控制器。这是有意的。
灰色背景是包含视图控制器的颜色。如您所见,黑色 MenuLoggedOutViewController
只下降了这么远。
任何人都可以向我解释一下,尽管几乎相同并且使用几乎相同的代码调用,为什么 MenuLoggedOutViewController
无法正确显示?
需要注意的是,如果屏幕旋转到一边然后再回到纵向,MenuLoggedOutViewController
会自行纠正。然后 MenuLoggedOutViewController
看起来应该是这样(比如 MenuLoggedInViewController
)。
很难说清楚到底发生了什么。如果您真的想要,我建议您使用 NSStringFromCGRect
并检查各种 frame
值,我想您会看到发生了什么。
但关键的概念问题是此代码正在调整 viewDidLoad
中的 frame
值,但此时 frame
值并不可靠。我建议:
将子 frame
值的调整移动到 viewWillLayoutSubviews
。在这一点上,主视图的 frame
是可靠的。
如果使用自动布局,根本不要设置 frame
值,而是将这两个子视图的 setTranslatesAutoresizingMaskIntoConstraints
设置为 false
和然后添加约束(您可以在 viewDidLoad
中执行),其 VFL 实际上是:
V:|[master(50)][detail]|
H:|[master]|
H:|[detail]|
作为最后一个不相关的细节,在调用 addChildViewController
时,添加完子视图后,不要忘记为每个子视图控制器调用 didMoveToParentViewController
。
我有两个子视图控制器,据我所知它们是相同的,但是其中一个出现意外。
这两个子视图控制器称为 MenuLoggedInViewController
和 MenuLoggedOutViewController
。他们的容器视图控制器具有以下代码:
override func viewDidLoad() {
super.viewDidLoad()
// i comment out one of these two lines to produce the different results:
self.masterView = MenuLoggedOutViewController(nibName: "MenuLoggedOutViewController", bundle: nil)
// self.masterView = MenuLoggedInViewController(nibName: "MenuLoggedInViewController", bundle: nil)
self.detailView = RootViewController(nibName: "RootViewController", bundle: nil)
self.masterViewFrame = CGRectMake(0, 0, self.view.frame.width, 50)
self.detailViewFrame = CGRectMake(0, 50, self.view.frame.width, self.view.frame.height - 50)
self.addChildViewController(masterView!)
self.addChildViewController(detailView!)
self.view.addSubview(masterView!.view)
self.view.addSubview(detailView!.view)
masterView!.view.frame = masterViewFrame
// masterView!.view.bounds = masterViewFrame // - i tried this and it made no difference
detailView!.view.frame = detailViewFrame
}
MenuLoggedInViewController
和 MenuLoggedOutViewController
在它们的 swift 文件中有几乎相同的模板代码:
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
除了更改背景颜色外,我没有触及 .xib
文件。在完成 .xib
文件的设置后,它们 似乎 都是一样的。如果可以的话,我不会靠近故事板,所以我对它不太熟悉。但是我花了很长时间仔细检查两个 .xib
文件的所有值,除了背景颜色之外,我可以检测到它们之间没有区别。
如您所见,黑色 MenuLoggedInViewController
紧贴下方的白色视图控制器。这是有意的。
灰色背景是包含视图控制器的颜色。如您所见,黑色 MenuLoggedOutViewController
只下降了这么远。
任何人都可以向我解释一下,尽管几乎相同并且使用几乎相同的代码调用,为什么 MenuLoggedOutViewController
无法正确显示?
需要注意的是,如果屏幕旋转到一边然后再回到纵向,MenuLoggedOutViewController
会自行纠正。然后 MenuLoggedOutViewController
看起来应该是这样(比如 MenuLoggedInViewController
)。
很难说清楚到底发生了什么。如果您真的想要,我建议您使用 NSStringFromCGRect
并检查各种 frame
值,我想您会看到发生了什么。
但关键的概念问题是此代码正在调整 viewDidLoad
中的 frame
值,但此时 frame
值并不可靠。我建议:
将子
frame
值的调整移动到viewWillLayoutSubviews
。在这一点上,主视图的frame
是可靠的。如果使用自动布局,根本不要设置
frame
值,而是将这两个子视图的setTranslatesAutoresizingMaskIntoConstraints
设置为false
和然后添加约束(您可以在viewDidLoad
中执行),其 VFL 实际上是:V:|[master(50)][detail]| H:|[master]| H:|[detail]|
作为最后一个不相关的细节,在调用 addChildViewController
时,添加完子视图后,不要忘记为每个子视图控制器调用 didMoveToParentViewController
。