【问题标题】:How to add constraints programmatically using Swift如何使用 Swift 以编程方式添加约束
【发布时间】:2014-11-28 14:56:40
【问题描述】:

自上周以来,我一直在尝试解决这个问题,但没有更进一步。好的,所以我需要使用以下代码将 Swift 中的一些 约束 以编程方式 应用到 UIView:

var new_view:UIView! = UIView(frame: CGRectMake(0, 0, 100, 100));
new_view.backgroundColor = UIColor.redColor();
view.addSubview(new_view);

var constX:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0);
self.view.addConstraint(constX);

var constY:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0);
self.view.addConstraint(constY);

var constW:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: new_view, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0);
self.view.addConstraint(constW);

var constH:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: new_view, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 0);
self.view.addConstraint(constH);

但是 Xcode 返回这个奇怪的输出:

2014-10-03 09:48:12.657 Test[35088:2454916] Unable to simultaneously satisfy constraints.  Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSLayoutConstraint:0x7fa4ea446830 UIView:0x7fa4ea429290.centerX == UIView:0x7fa4ea4470f0.centerX>",
"<NSAutoresizingMaskLayoutConstraint:0x7fa4ea4516c0 h=--& v=--& UIView:0x7fa4ea429290.midX == + 50>",
"<NSLayoutConstraint:0x7fa4ea452830 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fa4ea4470f0(375)]>",
"<NSAutoresizingMaskLayoutConstraint:0x7fa4ea446db0 h=-&- v=-&- 'UIView-Encapsulated-Layout-Left' H:|-(0)-[UIView:0x7fa4ea4470f0]   (Names: '|':UIWindow:0x7fa4ea444b20 )>"
)

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fa4ea446830 UIView:0x7fa4ea429290.centerX == UIView:0x7fa4ea4470f0.centerX>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in
<UIKit/UIView.h> may also be helpful.

2014-10-03 09:48:12.658 Test[35088:2454916] Unable to simultaneously satisfy constraints.  Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7fa4ea44d160 UIView:0x7fa4ea429290.centerY == UIView:0x7fa4ea4470f0.centerY>",
"<NSAutoresizingMaskLayoutConstraint:0x7fa4ea451b30 h=--& v=--& UIView:0x7fa4ea429290.midY == + 50>",
"<NSLayoutConstraint:0x7fa4ea44cf00 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa4ea4470f0(667)]>",
"<NSAutoresizingMaskLayoutConstraint:0x7fa4ea452700 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' V:|-(0)-[UIView:0x7fa4ea4470f0]  (Names: '|':UIWindow:0x7fa4ea444b20 )>"
)

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fa4ea44d160 UIView:0x7fa4ea429290.centerY == UIView:0x7fa4ea4470f0.centerY>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

你能帮帮我吗? 非常感谢

【问题讨论】:

标签: ios swift uiview autolayout nslayoutconstraint


【解决方案1】:

您是否计划在UIViewController 的UIView 中居中放置一个宽度:100 和高度:100 的平方UIView?如果是这样,您可以尝试以下 6 种自动布局样式之一(Swift 5 / iOS 12.2):


1。使用NSLayoutConstraint 初始化器

override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)
    let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)
    let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)
    view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)
    let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)
    let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)
    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true
    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true
}

2。使用视觉格式语言

override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let views = ["view": view!, "newView": newView]
    let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterY, metrics: nil, views: views)
    let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterX, metrics: nil, views: views)
    view.addConstraints(horizontalConstraints)
    view.addConstraints(verticalConstraints)
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let views = ["view": view!, "newView": newView]
    let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterY, metrics: nil, views: views)
    let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterX, metrics: nil, views: views)
    NSLayoutConstraint.activate(horizontalConstraints)
    NSLayoutConstraint.activate(verticalConstraints)
}

3。混合使用 NSLayoutConstraint 初始化程序和可视格式语言

override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let views = ["newView": newView]
    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)
    let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)
    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)
    view.addConstraints(widthConstraints)
    view.addConstraints(heightConstraints)
    view.addConstraints([horizontalConstraint, verticalConstraint])
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let views = ["newView": newView]
    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)
    let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)
    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)
    NSLayoutConstraint.activate(widthConstraints)
    NSLayoutConstraint.activate(heightConstraints)
    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = false
    let views = ["newView": newView]
    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)
    let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)
    NSLayoutConstraint.activate(widthConstraints)
    NSLayoutConstraint.activate(heightConstraints)
    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true
}

4。使用UIView.AutoresizingMask

注意:Springs 和 Struts 会在运行时翻译成相应的自动布局约束。

override func viewDidLoad() {
    let newView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)

    newView.translatesAutoresizingMaskIntoConstraints = true
    newView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
    newView.autoresizingMask = [UIView.AutoresizingMask.flexibleLeftMargin, UIView.AutoresizingMask.flexibleRightMargin, UIView.AutoresizingMask.flexibleTopMargin, UIView.AutoresizingMask.flexibleBottomMargin]
}

5。使用NSLayoutAnchor

override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)
    
    newView.translatesAutoresizingMaskIntoConstraints = false
    let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
    let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 100)
    let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 100)
    view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)
    
    newView.translatesAutoresizingMaskIntoConstraints = false
    let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
    let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 100)
    let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 100)
    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
override func viewDidLoad() {
    let newView = UIView()
    newView.backgroundColor = UIColor.red
    view.addSubview(newView)
    
    newView.translatesAutoresizingMaskIntoConstraints = false
    newView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    newView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    newView.widthAnchor.constraint(equalToConstant: 100).isActive = true
    newView.heightAnchor.constraint(equalToConstant: 100).isActive = true
}

6。使用intrinsicContentSize 和NSLayoutAnchor

import UIKit

class CustomView: UIView {
    
    override var intrinsicContentSize: CGSize {
        return CGSize(width: 100, height: 100)
    }
    
}

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        let newView = CustomView()
        newView.backgroundColor = UIColor.red
        view.addSubview(newView)
        
        newView.translatesAutoresizingMaskIntoConstraints = false
        let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
    }
    
}

结果:

【讨论】:

  • 有没有办法为锚样式约束设置动画?
  • 我不知道选项 5 / 锚样式,我真的很喜欢它,因为它最适合我正在尝试做的模型。但是因为我不倾向于在添加约束后更新它们,所以我使用了一种在创建它们的同时激活它们的速记:例如newView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
  • 如果你想要偏移量,例如使用这个 let h = newView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: 80) 或 let w = updatesAvailablePopover.centerYAnchor.constraintEqualToAnchor(view.topAnchor, constant: 100)
  • @JoeHuang 不,如果您想在将来更改约束,速记不起作用,因为速记正在创建新的约束。如果您希望引用以在将来更新约束,则需要使用 Imanou 在答案中使用的锚样式:)
  • 别忘了newView.translatesAutoresizingMaskIntoConstraints = false 部分!我花了一段时间才看到。
【解决方案2】:

它帮助我从视觉上学习,所以这是一个补充答案。

样板代码

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView()
    myView.backgroundColor = UIColor.blue
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    // Add constraints code here
    // ...
}

以下每个示例都独立于其他示例。

固定左边缘

myView.leading = leadingMargin + 20

方法一:锚样式

let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
  • 除了leadingAnchor,还有trailingAnchor、topAnchor、bottomAnchor。

方法二:NSLayoutConstraint 样式

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 20.0).isActive = true
  • 除了.leading,还有.trailing、.top和.bottom。
  • 除了.leadingMargin,还有.trailingMargin、.topMargin和.bottomMargin。

设置宽度和高度

width = 200
height = 100

方法一:锚样式

myView.widthAnchor.constraint(equalToConstant: 200).isActive = true
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true

方法二:NSLayoutConstraint 样式

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 200).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true

容器中心

myView.centerX = centerX
myView.centerY = centerY

方法一:锚样式

myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

方法二:NSLayoutConstraint 样式

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0).isActive = true

注意事项

  • 锚样式是优于NSLayoutConstraint 样式的首选方法,但它仅适用于iOS 9,因此如果您支持iOS 8,则仍应使用NSLayoutConstraint 样式。
  • 上面的例子只显示了被关注的一两个约束。但是,为了在我的测试项目中正确放置 myView,我需要有四个约束。

进一步阅读

【讨论】:

  • 非常好!一个小提示:只应指定leading 与centerX 约束中的一个。
  • @Cyber​​Dude,是的,你是对的。我的意思是上面的所有例子都是相互独立的,而不是把所有的约束都添加到同一个视图中。不过,这并不像我希望的那样清楚。
  • 您在view 上遗漏了必要的addConstraint() 以使布局约束注册。
【解决方案3】:

如果您想填充您的超级视图,那么我建议您使用 swifty 方式:

    view.translatesAutoresizingMaskIntoConstraints = false
    let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left]
    NSLayoutConstraint.activate(attributes.map {
        NSLayoutConstraint(item: view, attribute: $0, relatedBy: .equal, toItem: view.superview, attribute: $0, multiplier: 1, constant: 0)
    })

如果您需要非相等约束,请查看 iOS 9 中的 NSLayoutAnchor。直接使用 NSLayoutConstraint 通常更容易阅读:

    view.translatesAutoresizingMaskIntoConstraints = false
    view.topAnchor.constraint(equalTo: view.superview!.topAnchor).isActive = true
    view.bottomAnchor.constraint(equalTo: view.superview!.bottomAnchor).isActive = true
    view.leadingAnchor.constraint(equalTo: view.superview!.leadingAnchor, constant: 10).isActive = true
    view.trailingAnchor.constraint(equalTo: view.superview!.trailingAnchor, constant: 10).isActive = true

【讨论】:

  • 基于此moment of WWDC video。逐个激活约束通常效率不高,即执行isActive = true 并不总是一个好主意。将相关约束组合成一个并使用NSLayoutConstraint.activate 一次性激活它们会更好,性能更好。
【解决方案4】:

游乐场中多个视图的约束。

swift 3+

  var yellowView: UIView!
    var redView: UIView!

    override func loadView() {

        // UI

        let view = UIView()
        view.backgroundColor = .white

        yellowView = UIView()
        yellowView.backgroundColor = .yellow
        view.addSubview(yellowView)

        redView = UIView()
        redView.backgroundColor = .red
        view.addSubview(redView)

        // Layout
        redView.translatesAutoresizingMaskIntoConstraints = false
        yellowView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            yellowView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
            yellowView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            yellowView.widthAnchor.constraint(equalToConstant: 80),
            yellowView.heightAnchor.constraint(equalToConstant: 80),

            redView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20),
            redView.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20),
            redView.widthAnchor.constraint(equalToConstant: 80),
            redView.heightAnchor.constraint(equalToConstant: 80)
            ])

        self.view = view
    }

在我看来,xcode 游乐场是学习添加的最佳场所 以编程方式约束。

【讨论】:

    【解决方案5】:

    我们可以在 swift 5.1 中轻松做到这一点

    设置 1

    • 子视图与视图中心对齐
    • 使用浮动设置子视图宽度高度

      view.addSubview(myView1)
      myView1.translatesAutoresizingMaskIntoConstraints = false
      NSLayoutConstraint.activate([
          myView1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
          myView1.centerYAnchor.constraint(equalTo: view.centerYAnchor),
          myView1.widthAnchor.constraint(equalToConstant: 100),
          myView1.heightAnchor.constraint(equalToConstant: 100),
      ])
      

    设置 2

    • 子视图与视图前导和顶部锚点对齐
    • 使用视图宽度高度设置子视图宽度

          view.addSubview(myView2)
          myView2.translatesAutoresizingMaskIntoConstraints = false
      
          NSLayoutConstraint.activate([
              myView2.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 16),
              myView2.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 16),
              myView2.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.3),
              myView2.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3)
          ])
      

    【讨论】:

      【解决方案6】:

      基本上它涉及 3 个步骤

      fileprivate func setupName() { 
      
          lblName.text = "Hello world"
      
          // Step 1
          lblName.translatesAutoresizingMaskIntoConstraints = false
      
          //Step 2
          self.view.addSubview(lblName)
      
          //Step 3
          NSLayoutConstraint.activate([
              lblName.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
              lblName.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
          ])
      }
      

      这会将标签“hello world”放在屏幕中心。

      请参考链接Autolayout constraints programmatically

      【讨论】:

        【解决方案7】:

        正如错误消息所暗示的那样,问题在于您的 NSAutoresizingMaskLayoutConstraints 类型的约束与您的显式约束冲突,因为 new_view.translatesAutoresizingMaskIntoConstraints 设置为 true。

        这是您在代码中创建的视图的默认设置。你可以这样关闭它:

        var new_view:UIView! = UIView(frame: CGRectMake(0, 0, 100, 100))
        new_view.translatesAutoresizingMaskIntoConstraints = false
        

        另外,您的宽度和高度限制很奇怪。如果您希望视图具有恒定的宽度,这是正确的方法:

        new_view.addConstraint(NSLayoutConstraint(
            item:new_view, attribute:NSLayoutAttribute.Width,
            relatedBy:NSLayoutRelation.Equal,
            toItem:nil, attribute:NSLayoutAttribute.NotAnAttribute,
            multiplier:0, constant:100))
        

        (将 100 替换为您想要的宽度。)

        如果您的部署目标是 iOS 9.0 或更高版本,您可以使用以下更短的代码:

        new_view.widthAnchor.constraintEqualToConstant(100).active = true
        

        无论如何,对于这样的布局(固定大小并在父视图中居中),使用自动调整掩码并让系统将掩码转换为约束会更简单:

        var new_view:UIView! = UIView(frame: CGRectMake(0, 0, 100, 100))
        new_view.backgroundColor = UIColor.redColor();
        view.addSubview(new_view);
        
        // This is the default setting but be explicit anyway...
        new_view.translatesAutoresizingMaskIntoConstraints = true
        
        new_view.autoresizingMask = [ .FlexibleTopMargin, .FlexibleBottomMargin,
            .FlexibleLeftMargin, .FlexibleRightMargin ]
        
        new_view.center = CGPointMake(view.bounds.midX, view.bounds.midY)
        

        请注意,即使您还使用自动布局,使用自动调整大小也是完全合法的。 (UIKit 在内部的很多地方仍然使用自动调整大小。)问题是很难对使用自动调整大小的视图应用额外的约束。

        【讨论】:

        • 如果 UIKit 在内部使用自动调整大小可以解释锚定在中心的约束的不当行为吗?当我将 UIButton 的集合组织为 UIview 的子类时,锚约束似乎起作用,但当我将它们组织为视图控制器中的函数时,它们不起作用。如果您有空,可以看看这篇文章 [stackoverflow.com/questions/40650951/…‌ ler-we-cant-actually-add-any-new-fences-due]
        • 不,这并不能解释代码的不当行为。
        【解决方案8】:

        为 Swift 3 更新

        import UIKit
        
        class ViewController: UIViewController {
        
        let redView: UIView = {
        
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.backgroundColor = .red
            return view
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
        
            setupViews()
            setupAutoLayout()
        }
        
        func setupViews() {
        
            view.backgroundColor = .white
            view.addSubview(redView)
        }
        
        func setupAutoLayout() {
        
            // Available from iOS 9 commonly known as Anchoring System for AutoLayout...
            redView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
            redView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true
        
            redView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
            redView.heightAnchor.constraint(equalToConstant: 300).isActive = true
        
            // You can also modified above last two lines as follows by commenting above & uncommenting below lines...
            // redView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
            // redView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
         }
        }
        

        约束类型

         /*
        // regular use
        1.leftAnchor
        2.rightAnchor
        3.topAnchor
        // intermediate use
        4.widthAnchor
        5.heightAnchor
        6.bottomAnchor
        7.centerXAnchor
        8.centerYAnchor
        // rare use
        9.leadingAnchor
        10.trailingAnchor
        etc. (note: very project to project)
        */
        

        【讨论】:

        • 别忘了加,youViewName.translatesAutoresizingMaskIntoConstraints = false
        【解决方案9】:

        自动布局是通过对图像应用约束来实现的。使用 NSLayoutConstraint。可以在所有设备上实现理想而美观的设计。请尝试以下代码。

        import UIKit
        
        class ViewController: UIViewController {
        
        override func viewDidLoad() {
        super.viewDidLoad()
        
        let myImageView:UIImageView = UIImageView()
        myImageView.backgroundColor = UIColor.red
        myImageView.image = UIImage(named:"sample_dog")!
        myImageView.translatesAutoresizingMaskIntoConstraints = false
        myImageView.layer.borderColor = UIColor.red.cgColor
        myImageView.layer.borderWidth = 10
        self.view.addSubview(myImageView)
                
        view.removeConstraints(view.constraints)
        
        
        view.addConstraint(NSLayoutConstraint(
        item: myImageView,
        attribute: .top,
        relatedBy: .equal,
        toItem: view,
        attribute: .top,
        multiplier: 1,
        constant:100)
            
        )
        
        view.addConstraint(NSLayoutConstraint(
        item: myImageView,
        attribute: .centerX,
        relatedBy: .equal,
        toItem: view,
        attribute: .centerX,
        multiplier: 1,
        constant:0)
        )
            
        view.addConstraint(NSLayoutConstraint(
        item: myImageView,
        attribute: .height,
        relatedBy: .equal,
        toItem: view,
        attribute: .width,
        multiplier: 0.5,
        constant:40))
            
        view.addConstraint(NSLayoutConstraint(
        item: myImageView,
        attribute: .width,
        relatedBy: .equal,
        toItem: view,
        attribute: .width,
        multiplier: 0.5,
        constant:40))
            
        }
        
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
        }
        

        【讨论】:

          【解决方案10】:

          想在 Imanou Petit 的回答中添加一些理论概念,以便了解自动布局的工作原理。

          要了解自动布局,请将您的视图视为橡胶对象,它最初会缩小。

          要在屏幕上放置一个对象,我们需要 4 个必备的东西:

          • 对象的X坐标(水平位置)。

          • 物体的Y坐标(垂直位置)

          • 对象的宽度

          • 对象的高度。

          1 X 坐标:有多种方法可以为视图提供 x 坐标。

          如前导约束、尾随约束、水平居中 等等

          2 Y 坐标: 有多种方法可以为视图提供 y 坐标:

          如顶部约束、底部约束、垂直居中等

          3 对象的宽度:有两种方法可以给视图提供宽度约束:

          一个。添加固定宽度约束(将此约束视为固定宽度的铁棒,并且您已将橡胶物体水平钩住,因此橡胶物体不会收缩或膨胀)

          b.不要添加任何宽度约束,而是将 x 坐标约束添加到视图尾随和前导的两端,这两个约束将通过从前导和尾随两端拉/推橡胶对象来扩展/收缩橡胶对象。

          4 对象的高度: 与宽度类似,也有两种方法可以对视图进行高度限制:

          一个。添加固定高度约束(将此约束视为固定高度的铁棒,并且您已将橡胶物体垂直钩住,因此橡胶物体不会收缩或膨胀)

          b.不要添加任何高度约束,而是在视图顶部和底部添加 x 坐标约束,这两个约束将扩大/缩小橡胶的对象从两端、顶部和底部拉/推它。

          【讨论】:

            【解决方案11】:

            在 xcode 7.3.1 中有点不同。这就是我想出的

               // creating the view
                    let newView = UIView()
                    newView.backgroundColor = UIColor.redColor()
                    newView.translatesAutoresizingMaskIntoConstraints = false
                    view.addSubview(newView)
            
                    // creating the constraint 
            
                    // attribute and relation cannot be set directyl you need to create a cariable of them
                    let layout11 = NSLayoutAttribute.CenterX
                    let layout21 = NSLayoutRelation.Equal
                    let layout31 = NSLayoutAttribute.CenterY
                    let layout41 = NSLayoutAttribute.Width
                    let layout51 = NSLayoutAttribute.Height
                    let layout61 = NSLayoutAttribute.NotAnAttribute
            
                    // defining all the constraint
                    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: layout11, relatedBy: layout21, toItem: view, attribute: layout11, multiplier: 1, constant: 0)
                    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: layout31, relatedBy: layout21, toItem: view, attribute: layout31, multiplier: 1, constant: 0)
                    let widthConstraint = NSLayoutConstraint(item: newView, attribute: layout41, relatedBy: layout21, toItem: nil, attribute: layout61, multiplier: 1, constant: 100)
                    let heightConstraint = NSLayoutConstraint(item: newView, attribute: layout51, relatedBy: layout21, toItem: nil, attribute: layout61, multiplier: 1, constant: 100)
            
                    // adding all the constraint
                    NSLayoutConstraint.activateConstraints([horizontalConstraint,verticalConstraint,widthConstraint,heightConstraint])
            

            【讨论】:

            • translatesAutoresizingMaskIntoConstraints = false :))
            【解决方案12】:

            这是以编程方式添加约束的一种方法

            override func viewDidLoad() {
                        super.viewDidLoad()
            
            
            let myLabel = UILabel()
                    myLabel.labelFrameUpdate(label: myLabel, text: "Welcome User", font: UIFont(name: "times new roman", size: 40)!, textColor: UIColor.red, textAlignment: .center, numberOfLines: 0, borderWidth: 2.0, BorderColor: UIColor.red.cgColor)
                    self.view.addSubview(myLabel)
            
            
                     let myLabelhorizontalConstraint = NSLayoutConstraint(item: myLabel, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)
                    let myLabelverticalConstraint = NSLayoutConstraint(item: myLabel, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)
                    let mylabelLeading = NSLayoutConstraint(item: myLabel, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.leading, multiplier: 1, constant: 10)
                    let mylabelTrailing = NSLayoutConstraint(item: myLabel, attribute: NSLayoutAttribute.trailing, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.trailing, multiplier: 1, constant: -10)
                    let myLabelheightConstraint = NSLayoutConstraint(item: myLabel, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 50)
                    NSLayoutConstraint.activate(\[myLabelhorizontalConstraint, myLabelverticalConstraint, myLabelheightConstraint,mylabelLeading,mylabelTrailing\])
            }
            
            extension UILabel
            {
                func labelFrameUpdate(label:UILabel,text:String = "This is sample Label",font:UIFont = UIFont(name: "times new roman", size: 20)!,textColor:UIColor = UIColor.red,textAlignment:NSTextAlignment = .center,numberOfLines:Int = 0,borderWidth:CGFloat = 2.0,BorderColor:CGColor = UIColor.red.cgColor){
                    label.translatesAutoresizingMaskIntoConstraints = false
                    label.text = text
                    label.font = font
                    label.textColor = textColor
                    label.textAlignment = textAlignment
                    label.numberOfLines = numberOfLines
                    label.layer.borderWidth = borderWidth
                    label.layer.borderColor = UIColor.red.cgColor
                }
            }
            

            【讨论】:

              【解决方案13】:
                  var xCenterConstraint : NSLayoutConstraint!
                  var yCenterConstraint: NSLayoutConstraint!
              
               xCenterConstraint = NSLayoutConstraint(item: self.view, attribute: .CenterX, relatedBy: .Equal, toItem: (Your view NAme), attribute: .CenterX, multiplier: 1, constant: 0)
                          self.view.addConstraint(xCenterConstraint)
              
               yCenterConstraint = NSLayoutConstraint(item: self.view, attribute: .CenterY, relatedBy: .Equal, toItem: (Your view Name), attribute: .CenterY, multiplier: 1, constant: 0)
                          self.view.addConstraint(yCenterConstraint)
              

              【讨论】:

              • 请解释代码以及它如何回答问题。
              【解决方案14】:

              如果你觉得上面的内容很丑。您应该考虑使用 DSL 进行约束。如SnapKit 使约束 API 更加用户友好

              view.snp.makeConstraints { make in
                  make.edges.equalToSuperview()
              }
              

              【讨论】:

                【解决方案15】:

                试试这个优雅的UIView 扩展来约束。你可以简单地做约束:

                
                 - firstView.coverWholeSuperview()
                 - firstView.constraints(size: CGSize(width: 44, height: 44), centerX: view.centerXAnchor, centerY: view.centerXAnchor)
                 - firstView.constraints(top: view.topAnchor, 
                                         leading: secondView.leadingAnchor, 
                                         bottom: view.bottomAnchor, 
                                         trailing: secondView.trailingAnchor, 
                                         padding: UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12))
                
                

                这是扩展,只需将其复制到您的项目中即可。

                extension UIView {
                    /// Attaches all sides of the receiver to its parent view
                    func coverWholeSuperview(margin: CGFloat = 0.0) {
                        let view = superview
                        layoutAttachTop(to: view, margin: margin)
                        layoutAttachBottom(to: view, margin: margin)
                        layoutAttachLeading(to: view, margin: margin)
                        layoutAttachTrailing(to: view, margin: margin)
                
                    }
                
                    /// Attaches the top of the current view to the given view's top if it's a superview of the current view
                    /// or to it's bottom if it's not (assuming this is then a sibling view).
                    @discardableResult
                    func layoutAttachTop(to: UIView? = nil, margin: CGFloat = 0.0) -> NSLayoutConstraint {
                
                        let view: UIView? = to ?? superview
                        let isSuperview = view == superview
                        let constraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal,
                                                            toItem: view, attribute: isSuperview ? .top : .bottom, multiplier: 1.0,
                                                            constant: margin)
                        superview?.addConstraint(constraint)
                
                        return constraint
                    }
                
                    /// Attaches the bottom of the current view to the given view
                    @discardableResult
                    func layoutAttachBottom(to: UIView? = nil, margin: CGFloat = 0.0, priority: UILayoutPriority? = nil) -> NSLayoutConstraint {
                
                        let view: UIView? = to ?? superview
                        let isSuperview = (view == superview) || false
                        let constraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal,
                                                            toItem: view, attribute: isSuperview ? .bottom : .top, multiplier: 1.0,
                                                            constant: -margin)
                        if let priority = priority {
                            constraint.priority = priority
                        }
                        superview?.addConstraint(constraint)
                
                        return constraint
                    }
                
                    /// Attaches the leading edge of the current view to the given view
                    @discardableResult
                    func layoutAttachLeading(to: UIView? = nil, margin: CGFloat = 0.0) -> NSLayoutConstraint {
                
                        let view: UIView? = to ?? superview
                        let isSuperview = (view == superview) || false
                        let constraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal,
                                                            toItem: view, attribute: isSuperview ? .leading : .trailing, multiplier: 1.0,
                                                            constant: margin)
                        superview?.addConstraint(constraint)
                
                        return constraint
                    }
                
                    /// Attaches the trailing edge of the current view to the given view
                    @discardableResult
                    func layoutAttachTrailing(to: UIView? = nil, margin: CGFloat = 0.0, priority: UILayoutPriority? = nil) -> NSLayoutConstraint {
                
                        let view: UIView? = to ?? superview
                        let isSuperview = (view == superview) || false
                        let constraint = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal,
                                                            toItem: view, attribute: isSuperview ? .trailing : .leading, multiplier: 1.0,
                                                            constant: -margin)
                        if let priority = priority {
                            constraint.priority = priority
                        }
                        superview?.addConstraint(constraint)
                
                        return constraint
                    }
                
                    // For anchoring View
                    struct AnchoredConstraints {
                        var top, leading, bottom, trailing, width, height, centerX, centerY: NSLayoutConstraint?
                    }
                
                    @discardableResult
                    func constraints(top: NSLayoutYAxisAnchor? = nil, leading: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil,
                                trailing: NSLayoutXAxisAnchor? = nil, padding: UIEdgeInsets = .zero, size: CGSize = .zero,
                                centerX: NSLayoutXAxisAnchor? = nil, centerY: NSLayoutYAxisAnchor? = nil,
                                centerXOffset: CGFloat = 0, centerYOffset: CGFloat = 0) -> AnchoredConstraints {
                
                        translatesAutoresizingMaskIntoConstraints = false
                        var anchoredConstraints = AnchoredConstraints()
                
                        if let top = top {
                            anchoredConstraints.top = topAnchor.constraint(equalTo: top, constant: padding.top)
                        }
                
                        if let leading = leading {
                            anchoredConstraints.leading = leadingAnchor.constraint(equalTo: leading, constant: padding.left)
                        }
                
                        if let bottom = bottom {
                            anchoredConstraints.bottom = bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom)
                        }
                
                        if let trailing = trailing {
                            anchoredConstraints.trailing = trailingAnchor.constraint(equalTo: trailing, constant: -padding.right)
                        }
                
                        if size.width != 0 {
                            anchoredConstraints.width = widthAnchor.constraint(equalToConstant: size.width)
                        }
                
                        if size.height != 0 {
                            anchoredConstraints.height = heightAnchor.constraint(equalToConstant: size.height)
                        }
                
                        if let centerX = centerX {
                            anchoredConstraints.centerX = centerXAnchor.constraint(equalTo: centerX, constant: centerXOffset)
                        }
                
                        if let centerY = centerY {
                            anchoredConstraints.centerY = centerYAnchor.constraint(equalTo: centerY, constant: centerYOffset)
                        }
                
                        [anchoredConstraints.top, anchoredConstraints.leading, anchoredConstraints.bottom,
                         anchoredConstraints.trailing, anchoredConstraints.width,
                         anchoredConstraints.height, anchoredConstraints.centerX,
                         anchoredConstraints.centerY].forEach { $0?.isActive = true }
                
                        return anchoredConstraints
                    }
                }
                

                【讨论】:

                  【解决方案16】:

                  以下代码在这种情况下适用于我:UIImageView 强制景观。

                      imagePreview!.isUserInteractionEnabled = true
                      imagePreview!.isExclusiveTouch = true
                      imagePreview!.contentMode = UIView.ContentMode.scaleAspectFit
                      
                      // Remove all constraints
                      imagePreview!.removeAllConstraints()
                      
                      // Add the new constraints
                      let guide = view.safeAreaLayoutGuide
                      imagePreview!.translatesAutoresizingMaskIntoConstraints = false
                      imagePreview!.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
                      imagePreview!.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
                      imagePreview!.heightAnchor.constraint(equalTo: guide.heightAnchor, multiplier: 1.0).isActive = true
                  

                  其中 removeAllConstraints 是一个扩展

                  extension UIView {
                      
                      func removeAllConstraints() {
                          var _superview = self.superview
                          
                          func removeAllConstraintsFromView(view: UIView) { for c in view.constraints { view.removeConstraint(c) } }
                          
                          while let superview = _superview {
                              for constraint in superview.constraints {
                                  
                                  if let first = constraint.firstItem as? UIView, first == self {
                                      superview.removeConstraint(constraint)
                                  }
                                  
                                  if let second = constraint.secondItem as? UIView, second == self {
                                      superview.removeConstraint(constraint)
                                  }
                              }
                              
                              _superview = superview.superview
                          }
                          
                          self.removeConstraints(self.constraints)
                          self.translatesAutoresizingMaskIntoConstraints = true
                      }
                  }
                  

                  【讨论】:

                  • 一些建议:我永远不会强行打开一些东西。在访问可选项之前始终保持警惕,否则您会遇到一些崩溃。此外,您不需要删除所有约束。这是对处理能力的浪费,并可能导致问题。只需在 viewDidLoad 或 init 函数中添加视图加载时所需的约束即可。
                  【解决方案17】:

                  您将所有已定义的约束添加到 self.view,这是错误的,因为应将宽度和高度约束添加到您的 newView。

                  另外,据我了解,您希望将宽度和高度设置为 100:100。 在这种情况下,您应该将代码更改为:

                  var constW = NSLayoutConstraint(item: newView, 
                      attribute: .Width, 
                      relatedBy: .Equal, 
                      toItem: nil, 
                      attribute: .NotAnAttribute, 
                      multiplier: 1, 
                      constant: 100)
                  newView.addConstraint(constW)
                  
                  var constH = NSLayoutConstraint(item: newView, 
                      attribute: .Height, 
                      relatedBy: .Equal, 
                      toItem: nil, 
                      attribute: .NotAnAttribute, 
                      multiplier: 1, 
                      constant: 100)
                  newView.addConstraint(constH)
                  

                  【讨论】:

                    【解决方案18】:

                    您可以使用Snapkit 以编程方式设置约束。

                    class ViewController: UIViewController {
                        
                        let rectView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
                        
                        override func viewDidLoad() {
                            super.viewDidLoad()
                            setupViews()
                        }
                        
                        private func setupViews() {
                            rectView.backgroundColor = .red
                            view.addSubview(rectView)
                    
                            rectView.snp.makeConstraints {
                              $0.center.equalToSuperview()
                            }
                        }
                    }
                    

                    【讨论】:

                      【解决方案19】:

                      该错误是由自动调整掩码自动创建的约束引起的,它们是因为 UIView 属性 translatesAutoresizingMaskIntoConstraints 默认为 true 而创建的。

                      考虑使用BoxView 来摆脱所有手动创建约束的样板,并使您的代码简洁易读。使用 BoxView 制作有问题的布局非常简单:

                      boxView.items = [
                         new_view.boxed.centerX().centerY().relativeWidth(1.0).relativeHeight(1.0)
                      ]
                      

                      【讨论】:

                        猜你喜欢
                        • 2016-05-28
                        • 1970-01-01
                        • 2015-09-17
                        • 1970-01-01
                        • 1970-01-01
                        • 2020-05-12
                        相关资源
                        最近更新 更多