父 UIViewController 调整容器视图大小时,子视图控制器不自动布局

Posted

技术标签:

【中文标题】父 UIViewController 调整容器视图大小时,子视图控制器不自动布局【英文标题】:Child view controller does not auto layout when the parent UIViewController adjusts the size of the container view 【发布时间】:2015-01-30 16:57:45 【问题描述】:

我有一个带有容器视图的 UIViewController,并且我正在使用自动布局。我以编程方式将另一个视图控制器添加为子视图,并将其视图添加为子视图,并将视图框架设置为与容器视图相同。一切都很好,当我对容器视图的更改进行动画处理时,它会正确调整。如何让子视图控制器的视图调整大小?

子视图控制器实际上是一个以编程方式创建的导航控制器(称为 current_controller),并有一个使用自动布局的根视图控制器。这是我正在使用的方法(它在 Ruby 中,因为我正在使用 RubyMotion,但你会明白的)。我尝试将以下三行添加到完成块中,但它们没有任何效果。

  def shortcuts_hidden (hide)
    NSLog("setting shortcuts hidden to #hide")
    shortcuts_constraint.constant = hide ? shortcuts_view.frame.size.height : 0    
    UIView.animateWithDuration(
      0.25,
      animations: lambda 
        self.view.layoutIfNeeded
      ,
      completion: lambda  |completed|
        current_controller.view.frame.size.height = container_view.frame.size.height
        current_controller.view.layoutIfNeeded
        current_controller.viewControllers[0].view.layoutIfNeeded
      
    )
  end

用“解决方案”更新:

  def configure_constraints_for_view(controller_view)
    [NSLayoutAttributeLeft, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom].each do |attribute_name|
      self.view.addConstraint(
        NSLayoutConstraint.constraintWithItem(
          controller_view,
          attribute: attribute_name,
          relatedBy: NSLayoutRelationEqual,
          toItem: container_view,
          attribute: attribute_name,
          multiplier: 1.0,
          constant: 0
        )
      )
    end
  end

  def select_view_controller(index)
    if current_controller
      current_controller.removeFromParentViewController
      current_controller.view.removeFromSuperview
    end
    controller = view_controllers[index].build_menu_item
    controller.selected_from_menu = true
    @current_controller = UINavigationController.alloc.initWithRootViewController(controller)
    self.addChildViewController(current_controller)
    self.view.addSubview(current_controller.view)
    current_controller.view.translatesAutoresizingMaskIntoConstraints = false
    configure_constraints_for_view(current_controller.view)
    current_controller.didMoveToParentViewController(self)
  end

【问题讨论】:

【参考方案1】:

当您添加子视图时,您应该给它约束以使其与容器视图的大小相同,而不是设置它的框架。如果你这样做,那么它会在容器视图的边界发生变化时自动调整。

【讨论】:

太棒了!谢谢你,我试试看 解决了这个问题!有趣的是 current_controller 上的导航栏也动画下来了。如果我隐藏它然后显示它,它会出现在我期望的位置。我想这是一个单独的问题,因为导航控制器位于容器视图中,而容器视图本身位于另一个导航控制器中。【参考方案2】:

序言:Ruby 看起来很奇怪,但我对 RubyMotion 一无所知。在 ios 中,你不能直接设置视图的高度,你必须一次性设置它的框架。我将假设 RubyMotion 只是将它抽象化并允许你做这样荒谬的事情。


看起来您正在修改 current_controller.view 的框架,但您没有修改子视图控制器视图的框架。

    current_controller.view.frame.size.height = container_view.frame.size.height
    current_controller.view.layoutIfNeeded
    current_controller.viewControllers[0].view.frame.size.height = container_view.frame.size.height
    current_controller.viewControllers[0].view.layoutIfNeeded

我不知道这是否是您想要的度量,但它应该(可能)至少改变一些东西。

【讨论】:

首先,感谢您的宝贵时间。其次,恭喜:我复制并粘贴了您的 Ruby 代码,它运行时没有出现错误;-)。不幸的是,它没有帮助。

以上是关于父 UIViewController 调整容器视图大小时,子视图控制器不自动布局的主要内容,如果未能解决你的问题,请参考以下文章

关闭模态视图并调整父视图的大小?

将 UIViewController 的视图调整为父 UIWindow 的边界

当父容器视图约束以编程方式更改时,UINavigationController 子视图不调整大小

将两个 UIViewController 并排放在屏幕上

适当调整 UIViewController 的视图大小

UIViewController 的视图奇怪的调整大小行为