根据子视图

时间:2016-08-22 23:20:11

标签: ios uiview uikit ios-autolayout

我知道这个问题已被多次询问过,但我似乎无法深究这个问题。

使用自动布局,我想基于其子视图自动设置容器UIView的高度。我已经看过使用sizeToFit和其他各种方法来总结我的子视图的高度,但是根据我所读到的,当使用自动布局时,我的容器高度的高度应该是自动的,因为子视图“内在的”内容大小。

以下是我正在经历的简化案例。我真的很感激任何指导!

概述:

  1. 创建容器UIView,固定在superview的左右两侧,没有明确的高度,将其centerY与其superview centerY对齐
  2. 创建300宽度乘以100高度的UIView,将其作为子视图添加到容器视图,将其centerX与容器视图的centerX对齐,将pin与容器视图的上边缘对齐
  3. 重复步骤#2,除非此时将其顶部固定在#2的下边缘
  4. 容器视图的预期高度为200,但其高度实际上仍为0(因此中心对齐关闭)
  5. Issue visual

    代码:

    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
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

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

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