UIView 内部约束

Posted

技术标签:

【中文标题】UIView 内部约束【英文标题】:UIView internal constraints 【发布时间】:2019-02-26 12:17:14 【问题描述】:

我创建了一个简单的 UIView,它的中心包含一个红色框 (UIImage)。当所有约束都是常量时,代码可以正常工作。但是,如果我将高度约束替换为使框为视图高度一半的高度约束,那么框就会消失。

我认为这要么是因为我做错了(显然),要么我需要做更多的事情来强制约束实现 UIView 高度大于零。

如何设置 redBox 高度约束,使其始终为 BoxView 高度的一半?

import UIKit

class BoxView: UIView 

    public var redBox: UIImageView

    public override init(frame: CGRect) 
        redBox = UIImageView(frame: .zero)
        redBox.backgroundColor = .red

        super.init(frame: frame)
        self.backgroundColor = .yellow

        addSubview(redBox)
        redBox.translatesAutoresizingMaskIntoConstraints = false
        let margins = layoutMarginsGuide
        redBox.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        redBox.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        redBox.widthAnchor.constraint(equalToConstant: 100).isActive = true
      //redBox.heightAnchor.constraint(equalToConstant: 100).isActive = true
        redBox.heightAnchor.constraint(equalTo: self.heightAnchor, constant: 0.5)
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        view = BoxView()
    

【问题讨论】:

【参考方案1】:

替换

redBox.heightAnchor.constraint(equalTo: self.heightAnchor, constant: 0.5)

redBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.5).isActive = true

NSLayoutConstraint.activate([
    redBox.centerXAnchor.constraint(equalTo: self.centerXAnchor),
    redBox.centerYAnchor.constraint(equalTo: self.centerYAnchor),
    redBox.widthAnchor.constraint(equalToConstant: 100),
    redBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.5)
])

在您当前的代码中,首先您错过了.isActive = true,它的效果与该行不存在一样,如果指定,这将使框高度等于视图的高度+常量(= 0.5)

框高 = 视图高度 * 乘数 + 常数

并且由于默认乘数 = 1 并且您设置常量 = 0.5 这将是

框高 = 视图高度 * 1.0 + 0.5

但是你需要

box height = view height * 0.5 + 0 // 在约束中省略 consatnt,它将为零


class BoxView: UIView  
    public var redBox: UIImageView
    public override init(frame: CGRect) 
        super.init(frame: frame)
        redBox = UIImageView(frame: .zero)
        redBox.backgroundColor = .red
        self.backgroundColor = .yellow
        addSubview(redBox)
        redBox.translatesAutoresizingMaskIntoConstraints = false
        let margins = layoutMarginsGuide

        NSLayoutConstraint.activate([
            redBox.centerXAnchor.constraint(equalTo: self.centerXAnchor),
            redBox.centerYAnchor.constraint(equalTo: self.centerYAnchor),
            redBox.widthAnchor.constraint(equalToConstant: 100),
            redBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.5)
        ])
    
    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

@Paulw11 会做 不需要。我了解其中的区别,但没有发现错误。 (一行中有两个愚蠢的错误。)

以上是关于UIView 内部约束的主要内容,如果未能解决你的问题,请参考以下文章

约束 UIView 内的标签,该标签位于可扩展 collectionViewCell 内

以编程方式创建的 UIView 约束,未应用锚点

自动布局:使用 UIWebViews 自定义 UIView 高度约束

UIScrollView 中的 UIView 尊重一些约束,但不尊重其他约束

UISlider 约束以编程方式:“约束项必须每个都是 UIView 或子类的实例”

通过更新约束滑入 UIView