简体   繁体   English

根据子视图自动设置容器视图的高度

[英]Auto set height of container view based on subviews

I know this question has been asked numerous times, but I can't quite seem to get to the bottom of this problem. 我知道这个问题已经被问过无数次了,但是我似乎不太了解这个问题的根源。

Using Auto Layout, I would like to automatically set the height of my container UIView based on its subviews. 使用自动布局,我想基于其子视图自动设置容器UIView的高度。 I have looked at using sizeToFit and other various methods of summing up the height of my subviews, however from what I've read the height of my container height should be automatic when using Auto Layout because of the subviews "intrinsic" content size. 我已经看过使用sizeToFit和其他各种方法来汇总子视图的高度,但是根据我的了解,使用自动布局时,由于子视图的“内在”内容大小,容器高度应该是自动的。

Below is a reduced case of what I'm experiencing. 以下是我所遇到的情况的简化案例。 I would really appreciate any guidance! 我真的很感谢任何指导!

Overview: 概述:

  1. Create container UIView, pin to left and right sides of superview, no explicit height, align its centerY with its superview centerY 创建容器UIView,固定在超级视图的左侧和右侧,没有明确的高度,将其centerY与其超级视图centerY对齐
  2. Create a 300 width by 100 height UIView, add it as a subview to container view, align its centerX with container view's centerX, pin to container view's top edge 创建一个300宽度x 100高度的UIView,将其作为子视图添加到容器视图,将其centerX与容器视图的centerX对齐,固定到容器视图的顶部边缘
  3. Repeat step #2, except this time pin its top to #2's bottom edge 重复步骤2,但这次将其顶部固定在#2的底部边缘
  4. The expected height of the container view is 200, except its height is actually still 0 (therefor centerY alignment is off) 容器视图的预期高度为200,但其高度实际上仍为0(因此,centerY对齐已关闭)

发行视觉

Code: 码:

class ViewController: UIViewController {

    let redView = RedView()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(redView)
        view.setNeedsUpdateConstraints()
    }

}

class RedView: UIView {

    let greenView = GreenView()
    let blueView = BlueView()

    init() {
        super.init(frame: CGRect.zero)

        translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = UIColor.red()

        addSubview(greenView)
        addSubview(blueView)
        setNeedsUpdateConstraints()
    }

    override func updateConstraints() {
        super.updateConstraints()

        NSLayoutConstraint(item: greenView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: blueView, attribute: .top, relatedBy: .equal, toItem: greenView, attribute: .bottom, multiplier: 1, constant: 0).isActive = true

        NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: superview, attribute: .left, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: superview, attribute: .right, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: superview, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 200).isActive = true
    }

}

class GreenView: UIView {

    init() {
        super.init(frame: CGRect.zero)

        translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = UIColor.green()
    }

    override func updateConstraints() {
        super.updateConstraints()

        NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 300).isActive = true
        NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100).isActive = true
        NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: superview, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
    }

}

class BlueView: UIView {

    init() {
        super.init(frame: CGRect.zero)

        translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = UIColor.blue()
    }

    override func updateConstraints() {
        super.updateConstraints()

        NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 300).isActive = true
        NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100).isActive = true
        NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: superview, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
    }

}

您需要将blueView的底部固定到redView的底部,只需将此行添加到redView的updateConstraints

NSLayoutConstraint(item: blueView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0).active = true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM