首页 文章

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

提问于
浏览
313

自上周以来我一直试图解决这个问题,而没有更进一步 . 好的,所以我需要使用以下代码将 Swift 中的一些 constraints programmatically 应用于 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.

你能帮助我吗?非常感谢

15 回答

  • 11

    我在给定的图中创建了这些视图 . 以编程方式使用Autolayout . 您将深入了解约束以及如何正确应用它们 .

    你可以在这里参考"Introduction to Autolayout"

    enter image description here

  • 1

    你是否打算在 UIViewUIView 内设一个宽度为 UIView 的平方:100和高度:100?如果是这样,您可以尝试以下6种自动布局样式中的一种(Swift 4.2 / iOS 12):


    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初始化程序和Visual Format语言的混合

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

    结果:

    enter image description here

  • 0

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

    Boilerplate代码

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let myView = UIView()
        myView.backgroundColor = UIColor.blue
        myView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(myView)
    
        // Add constraints code here
        // ...
    }
    

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

    Pin左边缘

    myView.leading = leadingMargin + 20

    enter image description here

    Method 1: Anchor Style

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

    Method 2: NSLayoutConstraint Style

    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

    enter image description here

    Method 1: Anchor Style

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

    Method 2: NSLayoutConstraint Style

    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

    enter image description here

    Method 1: Anchor Style

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

    Method 2: NSLayoutConstraint Style

    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 Style的首选方法,但它仅适用于iOS 9,所以如果你支持iOS 8,那么你仍然应该使用 NSLayoutConstraint Style .

    • 上面的例子只显示了一个或两个正在关注的约束 . 但是,为了在我的测试项目中正确放置 myView ,我需要有四个约束 .

    进一步阅读

  • 783

    如果你想填写你的超级视图,那么我建议采用这种方式:

    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
    
  • 2

    正如错误消息所暗示的那样,问题是您的 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仍然在内部的许多地方使用自动调整 . )问题是很难将其他约束应用于使用自动调整大小的视图 .

  • 2

    操场上多个视图的约束 .

    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 playground是学习以编程方式添加约束的最佳位置 .

    Playground image

  • 196

    通过对图像应用约束来实现自动布局 . 使用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

    enter image description here

  • 3

    它在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])
    
  • 1

    Updated for 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

    Type of Constraints

    /*
    // 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)
    */
    
  • 21
    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)
    
  • 3

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

    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

  • 0

    Would like to add some theoretical concept to Imanou Petit’s answer, so that one can understand how auto layout works.

    要了解自动布局,请将您的视图视为最初收缩的 rubber's object .

    To place an object on screen we need 4 mandatory things :

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

    • 对象的Y坐标(垂直位置)

    • 对象的宽度

    • 物体的高度 .

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

    如前导约束,尾随约束,水平中心等 .

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

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

    3 Object's width: 有两种方法可以为视图提供宽度约束:

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

    b. Do not add any width constraint but add x coordinate constraint to both end of view trailing and leading, these two constraints will expand/shrink your rubber’s object by pulling/pushing it from both end, leading and trailing.

    4 Object's height: 与宽度类似,有两种方法可以为视图赋予高度约束:

    一个 . 添加固定高度约束(将此约束视为固定高度的铁杆,并且您已将橡胶的物体垂直地与其连接,因此橡胶的物体不会收缩或膨胀)

    b. Do not add any height constraint but add x coordinate constraint to both end of view top and bottom, these two constraints will expand/shrink your rubber’s object pulling/pushing it from both end, top and bottom.

  • 11

    如果你发现上面的丑陋 . 您应该考虑使用DSL进行约束 . 例如SnapKit使约束API更加用户友好

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

    基本上它涉及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

  • 4

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

相关问题