使用滚动视图内的动态大小的控制器调整容器视图的大小

Tem*_*son 64 uiscrollview ios autolayout uicontainerview

我正在尝试使用UIScrollView内部具有动态高度的控制器创建容器视图,并使用自动布局自动调整大小.

说明设置的故事板

视图控制器A是滚动视图,其中包含容器视图,以及下面的更多内容.

View Controller B是视图控制器,我希望它具有动态大小,并且所有内容都在View Controller A的Scroll View中以全高显示.

我有一些问题,让B的动态大小自动设置A中容器视图的大小.但是,如果我在A中的容器视图上设置高度约束 A中的容器视图例如250,

如果View Controller B也有250个高度,那么它将是预期的输出.它也适用于高度1000,所以据我所知,所有自动布局约束都正确设置.不幸的是,由于高度实际上应该是动态的,我想避免设置高度约束.

我不确定是否有任何设置视图控制器BI可以设置它根据其内容自动更新其大小,或者是否有任何其他技巧我错过了.任何帮助将非常感激!

根据视图控制器B的大小没有设置高度约束,有没有办法在A中调整容器视图的大小?

Mis*_*cha 102

是的,有.我设法在我自己的一个项目中实现了这种行为.

您要做的就是告诉系统它不应该在Interface Builder中添加模仿根视图的固定框架集的约束.执行此操作的最佳位置是在触发嵌入segue时的容器视图控制器中:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // You might want to check if this is your embed segue here
    // in case there are other segues triggered from this view controller. 
    segue.destinationViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
}
Run Code Online (Sandbox Code Playgroud)

重要:

您必须确保加载到容器中的视图从上到下受到约束,并且您需要将其中一个垂直约束的优先级设置为低于1000的值.(始终使用底部约束是一个好习惯为此.)这是必要的,因为否则Interface Builder会抱怨 - 有充分的理由:

在设计时,您的根视图具有固定大小(高度).现在,如果所有子视图都具有固定高度并且与具有相同优先级的固定约束连接,则除非固定根视图的高度恰好与子视图的总高度和垂直约束完全匹配,否则无法满足所有这些要求.如果将其中一个约束的优先级降低到999,Interface Builder就知道要断开哪个约束.但是在运行时 - 当translatesAutoresizingMaskIntoConstraints属性设置如上所述 - 根视图没有固定的框架,系统将使用您的999优先级约束.

Interface Builder截图

  • 如果转到Interface Builder中的Size Inspector,向下滚动并从*Intrinsic Content Size*下拉菜单中选择"Placeholder",您应该能够修复这些约束问题,而无需在容器视图上设置和删除约束.然后,您可以为容器视图设置固定的内部大小,该大小仅供Interface Builder用于布局视图但不在运行时应用. (13认同)
  • 这很好,谢谢!使用scrollview在编辑器中有一些约束问题,但是如果我在构建时删除的容器上设置了高度约束,那么这些问题就解决了. (2认同)

ace*_*lia 23

从@Mischa的答案我能够使containerView动态的高度取决于它的内容:

在containerView的viewController中写:

  override func loadView() {
    super.loadView()
    view.translatesAutoresizingMaskIntoConstraints = false
  }
Run Code Online (Sandbox Code Playgroud)

并注意IB中的垂直约束都已设定.这样做您不需要从视图控制器外部设置view.translatesAutoresizingMaskIntoConstraints = false.

在我的情况下,我试图将容器的大小调整为viewController中的tableView.因为tableView具有灵活的高度,具体取决于它的超级视图(所以对于IB都可以),我通过这样做完成了代码中的垂直约束:

  @IBOutlet private var tableView: UITableView! {
    didSet {
      tableView.addConstraint(tableViewHeight)
    }
  }
  private lazy var tableViewHeight: NSLayoutConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 0)
Run Code Online (Sandbox Code Playgroud)

然后观察tableview的contentSize高度,并在需要时以编程方式调整tableViewHeight约束的常量.


Teo*_*aru 13

Swift 4,Xcode 9

单独接受的答案并没有解决我的问题.

我的层次结构:ScrollView - >内容视图(UIView) - >视图| 容器视图| 其他观点.

我必须添加以下约束来使ScrollView和Container动态调整:

  1. ScrollView:顶部,底部,领先,追踪到Superview(安全区域)
  2. 内容视图:ScrollView的顶部,底部,前导,尾随,相等宽度,但也具有等高度(具有较低优先级的约束:250).
  3. 视图:正常的自动布局约束.
  4. 容器视图:顶部,底部到邻居视图,前导和尾随到安全区域.
  5. Container View的嵌入式VC:一切约束垂直连接,底部约束设置为较低的优先级,但大于Content View的Equal Height!在这种情况下,优先级为500就可以了.
  6. 设置view.translatesAutoresizingMaskIntoConstraints = false在任何一个prepareForSegue()loadView()其他答案中.

现在我在自动调整大小的Scroll View中有一个动态可调的容器视图.