在推入导航控制器的控制器中添加子视图控制器

Posted

技术标签:

【中文标题】在推入导航控制器的控制器中添加子视图控制器【英文标题】:Add children view controller in a controller that pushed in a navigation controller 【发布时间】:2016-02-02 12:01:45 【问题描述】:

我有一个简单的视图控制器,叫做 ViewController,它在一个导航栈中,结构如下:

UINavigationControlelr
  UIViewController
    ViewController

ViewController 有一个名为 a 的子视图控制器,我在 ViewController 中添加了一个,a 的框架是 ViewController 的边界。我有另外两个 UIViewController,分别称为 b 和 c,我将 b 和 c 添加到 a。 b的框架是

CGRect(x: 0, y: 0, width: 100, height: 100)

c的框架是

CGRect(x: 0, y: 100, width: 100, height: 100)

如果我将导航栏半透明设置为 true,则视图显示正确,如下所示:

但是当我将导航栏半透明设置为 false 时,发生了一些奇怪的事情。

发生了什么事。如何解决这个问题? 项目很简单,也可以从这里下载测试问题:download

【问题讨论】:

如果您还没有尝试过,查看调试器可能会有所帮助。 您的视图高度设置为 36,比您设置的高度正好小 64 像素,我会说这与插图有关。 是的,它被调用得太早了,当 ios 调整视图的框架以避免非半透明的黑条(即添加 64 像素到视图的 origin.y)时,您的子视图框架已经已经设置好了。回答如下。 【参考方案1】:

问题的原因默认是UIViewControllerviewFlexibleWidth & FlexibleHeight

bControllercControllerview 有 64 像素的额外间隙 (navBar(44) + 状态栏(20))。现在,当您调整大小时,它可以使用那些“FlexibleWidth&FlexibleHeight”。

解决方案可能是将autoresizingMask 改为.None

override func viewDidLoad() 
    super.viewDidLoad()

    view.backgroundColor = UIColor.greenColor()

    bController = b()
    cController = c()

    bController.view.autoresizingMask = .None
    cController.view.autoresizingMask = .None

    displayContentController(bController, toFrame: CGRect(x: 0, y: 0, width: 100, height: 100))
    displayContentController(cController, toFrame: CGRect(x: 0, y: 100, width: 100, height: 100))

【讨论】:

实际上,真正的问题是viewDidLoad 不是进行视图布局的正确位置。此外,既然我们已经使用了自动布局,我们真的应该停止使用 autoresizingMasks 来进行鞋喇叭布局。【参考方案2】:

您正在viewDidLoad 中设置视图框架,请注意视图布局直到很久以后才完成。 viewWillLayoutSubviewsviewDidLayoutSubviews 分别在布局发生之前和之后调用)。

将你的框架设置代码移动到viewDidLayoutSubviews,它就可以正常工作了。

注意::您也可以在 viewWillAppear 中设置视图的框架,但这是设置框架的正确位置。 viewWillAppear 在视图即将出现之前调用,视图布局可以在视图出现后更改(例如响应设备旋转)。

【讨论】:

谢谢,我在 viewDidLayoutSubviews 中设置了视图框架,它可以工作。但在 viewWillAppear 中,它不起作用。我在 viewDidAppear 中设置了视图框架,它可以工作。 我不建议使用viewWillAppear,如果您阅读了我的回答,这似乎令人沮丧,因为即使有时它可能有效,但并不总是有效。

以上是关于在推入导航控制器的控制器中添加子视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

将视图控制器推入导航控制器的问题

当视图控制器弹出或推入导航控制器堆栈时如何获得通知

在导航控制器中添加子视图覆盖导航栏

在导航控制器 xcode 中添加“子”视图

将相同的视图控制器推入堆栈有奇怪的行为

如何在不丢失导航栏的情况下将子视图添加到 UINavigation 控制器?