如何以编程方式创建布局约束
How to Create layout constraints programmatically
我在通用应用程序的底部显示一个视图,并在我的视图中动态添加该视图。我想每次都像 iAd 一样在底部显示这个视图。在两个方向。我该如何为此添加约束。请提出建议。
谢谢
要将视图固定到屏幕底部,您需要设置以下约束。
- 关于父视图的前导约束 - X
- 关于父视图的尾随约束 - 宽度
- 关于父视图的底部约束 - Y
- 身高约束 附加到自身 - 身高.
让我们添加。
UIView *subView=bottomView;
UIView *parent=self.view;
subView.translatesAutoresizingMaskIntoConstraints = NO;
//Trailing
NSLayoutConstraint *trailing =[NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:0.f];
//Leading
NSLayoutConstraint *leading = [NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeLeading
multiplier:1.0f
constant:0.f];
//Bottom
NSLayoutConstraint *bottom =[NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.f];
//Height to be fixed for SubView same as AdHeight
NSLayoutConstraint *height = [NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:0
constant:ADHeight];
//Add constraints to the Parent
[parent addConstraint:trailing];
[parent addConstraint:bottom];
[parent addConstraint:leading];
//Add height constraint to the subview, as subview owns it.
[subView addConstraint:height];
希望对您有所帮助。
干杯。
先前答案的小扩展,因为 addConstraint
将来会被弃用。这是 UI 视图的扩展。在将视图添加到层次结构后使用这些函数。
OBJC
@implementation UIView (Constraints)
-(void)addConstaintsToSuperviewWithLeftOffset:(CGFloat)leftOffset topOffset:(CGFloat)topOffset {
self.translatesAutoresizingMaskIntoConstraints = false;
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeLeading
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeLeading
multiplier: 1
constant: leftOffset] setActive:true];
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeTop
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeTop
multiplier: 1
constant: topOffset] setActive:true];
}
-(void)addConstaintsWithWidth:(CGFloat)width height:(CGFloat)height {
self.translatesAutoresizingMaskIntoConstraints = false;
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeWidth
relatedBy: NSLayoutRelationEqual
toItem: nil
attribute: NSLayoutAttributeNotAnAttribute
multiplier: 1
constant: width] setActive:true];
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeHeight
relatedBy: NSLayoutRelationEqual
toItem: nil
attribute: NSLayoutAttributeNotAnAttribute
multiplier: 1
constant: height] setActive:true];
}
@end
Swift 3
extension UIView {
public func addConstaintsToSuperview(leftOffset: CGFloat, topOffset: CGFloat) {
self.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self,
attribute: .leading,
relatedBy: .equal,
toItem: self.superview,
attribute: .leading,
multiplier: 1,
constant: leftOffset).isActive = true
NSLayoutConstraint(item: self,
attribute: .top,
relatedBy: .equal,
toItem: self.superview,
attribute: .top,
multiplier: 1,
constant: topOffset).isActive = true
}
public func addConstaints(height: CGFloat, width: CGFloat) {
self.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self,
attribute: .height,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1,
constant: height).isActive = true
NSLayoutConstraint(item: self,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1,
constant: width).isActive = true
}
}
此外,自 iOS 9 起,使用锚点可以非常简单地完成:
Swift 3
extension UIView {
func addConstaintsToSuperview(leadingOffset: CGFloat, topOffset: CGFloat) {
guard superview != nil else {
return
}
translatesAutoresizingMaskIntoConstraints = false
leadingAnchor.constraint(equalTo: superview!.leadingAnchor,
constant: leadingOffset).isActive = true
topAnchor.constraint(equalTo: superview!.topAnchor,
constant: topOffset).isActive = true
}
func addConstaints(height: CGFloat, width: CGFloat) {
heightAnchor.constraint(equalToConstant: height).isActive = true
widthAnchor.constraint(equalToConstant: width).isActive = true
}
}
OBJC 类别
@implementation UIView (Constraints)
-(void)addConstaintsToSuperviewWithLeadingOffset:(CGFloat)leadingOffset topOffset:(CGFloat)topOffset
{
if (self.superview == nil) {
return;
}
self.translatesAutoresizingMaskIntoConstraints = false;
[[self.leadingAnchor constraintEqualToAnchor:self.superview.leadingAnchor
constant:leadingOffset] setActive:true];
[[self.topAnchor constraintEqualToAnchor:self.superview.topAnchor
constant:topOffset] setActive:true];
}
-(void)addConstaintsWithHeight:(CGFloat)height width:(CGFloat)width
{
[[self.heightAnchor constraintEqualToConstant:height] setActive:true];
[[self.widthAnchor constraintEqualToConstant:width] setActive:true];
}
@end
在Swift 4 中扩展@Alex Shubin 解决方案,我执行以下操作:
有时,我需要添加可变数量的约束,在本例中为 3,因为高度将在后面计算。
keyboard.addConstaints(top: nil, right: 0.0, bottom: 0.0, left: 0.0, width: nil, height: nil)
您必须小心添加所有必需的内容,并确保您没有任何冲突的约束。
extension UIView {
func addConstaints(top: CGFloat?, right: CGFloat?, bottom: CGFloat?, left: CGFloat?, width: CGFloat?, height: CGFloat?) {
translatesAutoresizingMaskIntoConstraints = false
if top != nil { self.addConstaint(top: top!) }
if right != nil { self.addConstaint(right: right!) }
// Add lines for bottom, left, width an heigh
// ...
}
func addConstaint(top offset: CGFloat) {
guard superview != nil else { return }
topAnchor.constraint(equalTo: superview!.topAnchor, constant: offset).isActive = true
}
}
要验证所有视图的布局是否正确,您可以检查 superView 的 .constraints 属性 或检查框架:
override func viewDidLayoutSubviews() {
print(keyboard.frame)
}
您可以像下面这样以编程方式使用自动布局约束
fileprivate func setupName(){
let height = CGFloat(50)
lblName.text = "Hello world"
lblName.backgroundColor = .lightGray
//Step 1
lblName.translatesAutoresizingMaskIntoConstraints = false
//Step 2
self.view.addSubview(lblName)
//Step 3
NSLayoutConstraint.activate([
lblName.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
lblName.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
lblName.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor,constant: -height),
lblName.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
])
}
Output screenshot
我在通用应用程序的底部显示一个视图,并在我的视图中动态添加该视图。我想每次都像 iAd 一样在底部显示这个视图。在两个方向。我该如何为此添加约束。请提出建议。
谢谢
要将视图固定到屏幕底部,您需要设置以下约束。
- 关于父视图的前导约束 - X
- 关于父视图的尾随约束 - 宽度
- 关于父视图的底部约束 - Y
- 身高约束 附加到自身 - 身高.
让我们添加。
UIView *subView=bottomView;
UIView *parent=self.view;
subView.translatesAutoresizingMaskIntoConstraints = NO;
//Trailing
NSLayoutConstraint *trailing =[NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:0.f];
//Leading
NSLayoutConstraint *leading = [NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeLeading
multiplier:1.0f
constant:0.f];
//Bottom
NSLayoutConstraint *bottom =[NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.f];
//Height to be fixed for SubView same as AdHeight
NSLayoutConstraint *height = [NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:0
constant:ADHeight];
//Add constraints to the Parent
[parent addConstraint:trailing];
[parent addConstraint:bottom];
[parent addConstraint:leading];
//Add height constraint to the subview, as subview owns it.
[subView addConstraint:height];
希望对您有所帮助。
干杯。
先前答案的小扩展,因为 addConstraint
将来会被弃用。这是 UI 视图的扩展。在将视图添加到层次结构后使用这些函数。
OBJC
@implementation UIView (Constraints)
-(void)addConstaintsToSuperviewWithLeftOffset:(CGFloat)leftOffset topOffset:(CGFloat)topOffset {
self.translatesAutoresizingMaskIntoConstraints = false;
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeLeading
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeLeading
multiplier: 1
constant: leftOffset] setActive:true];
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeTop
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeTop
multiplier: 1
constant: topOffset] setActive:true];
}
-(void)addConstaintsWithWidth:(CGFloat)width height:(CGFloat)height {
self.translatesAutoresizingMaskIntoConstraints = false;
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeWidth
relatedBy: NSLayoutRelationEqual
toItem: nil
attribute: NSLayoutAttributeNotAnAttribute
multiplier: 1
constant: width] setActive:true];
[[NSLayoutConstraint constraintWithItem: self
attribute: NSLayoutAttributeHeight
relatedBy: NSLayoutRelationEqual
toItem: nil
attribute: NSLayoutAttributeNotAnAttribute
multiplier: 1
constant: height] setActive:true];
}
@end
Swift 3
extension UIView {
public func addConstaintsToSuperview(leftOffset: CGFloat, topOffset: CGFloat) {
self.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self,
attribute: .leading,
relatedBy: .equal,
toItem: self.superview,
attribute: .leading,
multiplier: 1,
constant: leftOffset).isActive = true
NSLayoutConstraint(item: self,
attribute: .top,
relatedBy: .equal,
toItem: self.superview,
attribute: .top,
multiplier: 1,
constant: topOffset).isActive = true
}
public func addConstaints(height: CGFloat, width: CGFloat) {
self.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self,
attribute: .height,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1,
constant: height).isActive = true
NSLayoutConstraint(item: self,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1,
constant: width).isActive = true
}
}
此外,自 iOS 9 起,使用锚点可以非常简单地完成:
Swift 3
extension UIView {
func addConstaintsToSuperview(leadingOffset: CGFloat, topOffset: CGFloat) {
guard superview != nil else {
return
}
translatesAutoresizingMaskIntoConstraints = false
leadingAnchor.constraint(equalTo: superview!.leadingAnchor,
constant: leadingOffset).isActive = true
topAnchor.constraint(equalTo: superview!.topAnchor,
constant: topOffset).isActive = true
}
func addConstaints(height: CGFloat, width: CGFloat) {
heightAnchor.constraint(equalToConstant: height).isActive = true
widthAnchor.constraint(equalToConstant: width).isActive = true
}
}
OBJC 类别
@implementation UIView (Constraints)
-(void)addConstaintsToSuperviewWithLeadingOffset:(CGFloat)leadingOffset topOffset:(CGFloat)topOffset
{
if (self.superview == nil) {
return;
}
self.translatesAutoresizingMaskIntoConstraints = false;
[[self.leadingAnchor constraintEqualToAnchor:self.superview.leadingAnchor
constant:leadingOffset] setActive:true];
[[self.topAnchor constraintEqualToAnchor:self.superview.topAnchor
constant:topOffset] setActive:true];
}
-(void)addConstaintsWithHeight:(CGFloat)height width:(CGFloat)width
{
[[self.heightAnchor constraintEqualToConstant:height] setActive:true];
[[self.widthAnchor constraintEqualToConstant:width] setActive:true];
}
@end
在Swift 4 中扩展@Alex Shubin 解决方案,我执行以下操作:
有时,我需要添加可变数量的约束,在本例中为 3,因为高度将在后面计算。
keyboard.addConstaints(top: nil, right: 0.0, bottom: 0.0, left: 0.0, width: nil, height: nil)
您必须小心添加所有必需的内容,并确保您没有任何冲突的约束。
extension UIView {
func addConstaints(top: CGFloat?, right: CGFloat?, bottom: CGFloat?, left: CGFloat?, width: CGFloat?, height: CGFloat?) {
translatesAutoresizingMaskIntoConstraints = false
if top != nil { self.addConstaint(top: top!) }
if right != nil { self.addConstaint(right: right!) }
// Add lines for bottom, left, width an heigh
// ...
}
func addConstaint(top offset: CGFloat) {
guard superview != nil else { return }
topAnchor.constraint(equalTo: superview!.topAnchor, constant: offset).isActive = true
}
}
要验证所有视图的布局是否正确,您可以检查 superView 的 .constraints 属性 或检查框架:
override func viewDidLayoutSubviews() {
print(keyboard.frame)
}
您可以像下面这样以编程方式使用自动布局约束
fileprivate func setupName(){
let height = CGFloat(50)
lblName.text = "Hello world"
lblName.backgroundColor = .lightGray
//Step 1
lblName.translatesAutoresizingMaskIntoConstraints = false
//Step 2
self.view.addSubview(lblName)
//Step 3
NSLayoutConstraint.activate([
lblName.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
lblName.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
lblName.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor,constant: -height),
lblName.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
])
}
Output screenshot