如何使用Swift以编程方式添加约束

从上周开始,我就一直在想办法解决这个问题。好的,所以我需要应用一些约束 以编程方式< em > < / em >斯威夫特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.
你能帮我吗? 非常感谢

641660 次浏览

你计划有一个平方UIView宽度:100身高:100居中的UIViewUIViewController?如果是这样,你可以尝试以下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. 使用# EYZ0

注意:spring和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. 使用# EYZ0

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. 使用intrinsicContentSizeNSLayoutAnchor

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

}

结果:

enter image description here

正如错误消息所显示的那样,问题在于类型为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仍然在内部的很多地方使用自动调整大小。)问题是很难对使用自动调整大小的视图应用额外的约束。

    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)

它帮助我直观地学习,所以这是一个补充答案。

样板代码

override func viewDidLoad() {
super.viewDidLoad()


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


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

下面的每个例子都是相互独立的。

引脚左边缘

# EYZ0

enter image description here

方法1:锚式

let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
  • 除了leadingAnchor,还有trailingAnchortopAnchorbottomAnchor

方法2: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

设置宽度和高度

< p > # EYZ0 < br > # EYZ0 < / p >

enter image description here

方法1:锚式

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

方法2: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

集装箱中心

< p > # EYZ0 < br > # EYZ0 < / p >

enter image description here

方法1:锚式

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

方法2: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,我需要有四个约束条件。

进一步的阅读

  • # EYZ0文档

你将所有定义的约束添加到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)

在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])

如果你想要填充你的超级视图,那么我建议快速的方法:

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

否则,如果你需要非相等的约束检查NSLayoutAnchor作为iOS 9。使用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

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

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

enter image description here

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

enter image description here

约束的类型

 /*
// 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)
*/

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

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

通过对图像施加约束来实现自动布局。使用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()
}
}

enter image description here # EYZ0 < / p >

操场上多个视图的约束。

斯威夫特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游乐场是学习加法最好的地方 通过编程方式约束。< / p >

Playground image .

基本上有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”置于屏幕中心。

请参考自动布局约束编程链接

想在Imanou Petit的回答中添加一些理论概念,这样人们就可以了解自动布局是如何工作的。

为了理解自动布局,把你的视图想象成橡胶的对象,它最初是收缩的。

要在屏幕上放置一个对象,我们需要4件强制性的事情:

  • 物体的X坐标(水平位置)。

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

  • 对象的宽度

  • 物体的高度。

给视图x坐标有多种方式。

如前向约束,后向约束,水平中心 等。< / em > < / p >

给视图y坐标有多种方式:

如顶部约束,底部约束,垂直中心等。

有两种方法来限制视图的宽度:

a.添加固定宽度约束(将此约束视为固定宽度的铁棒,并与橡胶对象水平挂钩,使橡胶对象不会收缩或膨胀)

# EYZ0

类似于width,也有两种方法来限制视图的高度:

a.添加固定高度约束(将此约束视为固定高度的铁棒,并与橡胶物体垂直挂钩,使橡胶物体不会收缩或膨胀)

# EYZ0

我们可以很容易地在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)
    ])
    

Result

尝试这个优雅的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
}
}

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

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

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

下面的代码为我工作在这个场景:一个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
}
}

您可以使用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()
}
}
}