Cách thêm các ràng buộc theo chương trình bằng Swift


448

Tôi đang cố gắng để tìm ra điều này kể từ tuần trước mà không tiến thêm bước nào. Ok, vì vậy tôi cần áp dụng một số ràng buộc theo chương trình trong Swift để UIViewsử dụng mã này:

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

Nhưng Xcode trả về đầu ra kỳ lạ này:

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.

Bạn có thể giúp tôi được không? Cảm ơn rất nhiều


1
Vui lòng dán thông báo lỗi dưới dạng khối mã, không phải là văn bản được trích dẫn. Điều đó có nghĩa là bạn cần đặt bốn khoảng trắng ở đầu mỗi dòng, không phải a >. Tôi đã sửa nó cho bạn lần này.
cướp mayoff

8
bạn đang thiếu "translateAutoresizingMaskIntoConstraint = false"
Christian 'fuzi' Orgler

1
Bạn có thể muốn sử dụng thư viện tuyệt vời này cho các ràng buộc năng động và đơn giản. github.com/SnapKit/SnapKit
Aashish

Hãy chắc chắn rằng bạn thấy Trên iOS, sự khác biệt giữa lề, phần chèn cạnh, phần nội dung, phần căn chỉnh, lề bố cục, phần neo . Nó sẽ cải thiện việc đưa ra quyết định của bạn giữa lề, neo, bố cục ...
Mật ong

đây là bài viết sẽ giải thích cách thêm các ràng buộc thông qua mã: slode.com/.com/
Shankar BS

Câu trả lời:


1056

Bạn có kế hoạch để có một hình vuông UIViewcủa width: 100Height: 100 trung tâm bên trongUIView của mộtUIViewController ? Nếu vậy, bạn có thể thử một trong 6 kiểu Bố cục tự động sau (Swift 5 / iOS 12.2):


1. Sử dụng bộ NSLayoutConstraintkhởi tạo

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. Sử dụng ngôn ngữ định dạng trực quan

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. Sử dụng kết hợp trình NSLayoutConstraintkhởi tạo và Ngôn ngữ định dạng trực quan

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. Sử dụng UIView.AutoresizingMask

Lưu ý: Springs và Struts sẽ được dịch thành các ràng buộc bố cục tự động tương ứng khi chạy.

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. Sử dụng 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. Sử dụng 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])
    }

}

Kết quả:

nhập mô tả hình ảnh ở đây


3
Có cách nào để làm động các ràng buộc kiểu neo không?
Liumx31

5
Tôi không biết về tùy chọn 5 / kiểu neo, tôi thực sự thích nó vì nó phù hợp nhất với mô hình của những gì tôi đang cố gắng thực hiện. Nhưng bởi vì tôi không có xu hướng cập nhật những hạn chế sau khi họ đã được thêm vào tôi sử dụng một cách viết tắt đó kích hoạt chúng cùng một lúc như tạo cho họ: ví dụnewView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
Mathews

nếu bạn muốn bù đắp, sử dụng này ví dụ để cho h = newView.centerXAnchor.constraintEqualToAnchor (view.centerXAnchor, liên tục: 80) hoặc cho phép w = updatesAvailablePopover.centerYAnchor.constraintEqualToAnchor (view.topAnchor, liên tục: 100)
DogCoffee

1
@JoeHuang không, tay ngắn không hoạt động nếu bạn muốn thay đổi ràng buộc trong tương lai vì tốc ký đang tạo ra một ràng buộc mới. Bạn sẽ cần sử dụng kiểu neo mà Imanou sử dụng trong câu trả lời nếu bạn muốn tham chiếu để cập nhật một ràng buộc trong tương lai :)
MathewS

1
Đừng quên newView.translatesAutoresizingMaskIntoConstraints = falsephần! Điều đó khiến tôi mất một lúc để xem.
huwr

247

Nó giúp tôi học trực quan, vì vậy đây là một câu trả lời bổ sung.

Mã nồi hơi

override func viewDidLoad() {
    super.viewDidLoad()

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

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

Mỗi ví dụ sau đây độc lập với các ví dụ khác.

Ghim cạnh trái

myView.leading = leadingMargin + 20

nhập mô tả hình ảnh ở đây

Cách 1: Kiểu neo

let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
  • Ngoài leadingAnchor, đó cũng là trailingAnchor, topAnchor, và bottomAnchor.

Phương pháp 2: Phong cách NSLayoutConstraint

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 20.0).isActive = true
  • Ngoài .leadingcòn có .trailing, .top.bottom.
  • Ngoài .leadingMargincòn có .trailingMargin, .topMargin.bottomMargin.

Đặt chiều rộng và chiều cao

width = 200
height = 100

nhập mô tả hình ảnh ở đây

Cách 1: Kiểu neo

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

Phương pháp 2: Phong cách 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

Trung tâm trong container

myView.centerX = centerX
myView.centerY = centerY

nhập mô tả hình ảnh ở đây

Cách 1: Kiểu neo

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

Phương pháp 2: Phong cách 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

Ghi chú

  • Kiểu neo là phương thức ưa thích hơn NSLayoutConstraintKiểu, tuy nhiên nó chỉ có sẵn từ iOS 9, vì vậy nếu bạn đang hỗ trợ iOS 8 thì bạn vẫn nên sử dụngNSLayoutConstraint Kiểu.
  • Các ví dụ trên chỉ cho thấy một hoặc hai ràng buộc đang được tập trung vào. Tuy nhiên, để đặt đúng vị trí myViewtrong dự án thử nghiệm của tôi, tôi cần phải có bốn ràng buộc.

Đọc thêm


2
Rất đẹp! Một lưu ý nhỏ: chỉ một trong những ràng buộc leadingso với centerXnên được chỉ định.
CyberDude

1
@CyberDude, vâng, bạn đúng. Tôi có nghĩa là cho tất cả các ví dụ ở trên là độc lập với nhau, không thêm tất cả các ràng buộc vào cùng một chế độ xem. Điều đó không rõ ràng như tôi muốn, mặc dù.
Suragch

Bạn còn lại ra cần thiết addConstraint()trên viewđể làm cho layoutconstraints đăng ký.
Martin

@Suragch Tuyệt vời;)
Amir Khan

34

Nếu bạn muốn lấp đầy siêu xem của mình thì tôi đề xuất cách thức khéo léo:

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

Thông thái khác nếu bạn cần các ràng buộc không bằng nhau, hãy kiểm tra NSLayoutAnchor kể từ iOS 9. Việc đọc trực tiếp bằng NSLayoutConstraint thường dễ dàng hơn nhiều:

    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

3
Dựa trên khoảnh khắc này của video WWDC . Nói chung, nó không hiệu quả để kích hoạt các ràng buộc từng cái một, tức isActive = truelà không phải lúc nào cũng là một ý tưởng tốt. Sẽ tốt hơn và hiệu quả hơn khi nhóm các ràng buộc liên quan thành một và kích hoạt tất cả chúng cùng một lúc bằng cách sử dụng NSLayoutConstraint.activate.
Mật ong

21

Những hạn chế cho nhiều quan điểm trong sân chơi.

nhanh hơn 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
    }

Theo tôi, sân chơi xcode là nơi tốt nhất để học thêm các ràng buộc theo chương trình.

Hình ảnh sân chơi


12

Vấn đề, như thông báo lỗi cho thấy, là bạn có các ràng buộc kiểu NSAutoresizingMaskLayoutConstraintsxung đột với các ràng buộc rõ ràng của mình, bởi vìnew_view.translatesAutoresizingMaskIntoConstraints được đặt thành đúng.

Đây là cài đặt mặc định cho các chế độ xem bạn tạo trong mã. Bạn có thể tắt nó như thế này:

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

Ngoài ra, các hạn chế chiều rộng và chiều cao của bạn là lạ. Nếu bạn muốn chế độ xem có chiều rộng không đổi, đây là cách thích hợp:

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

(Thay thế 100 bằng chiều rộng bạn muốn nó có.)

Nếu mục tiêu triển khai của bạn là iOS 9.0 trở lên, bạn có thể sử dụng mã ngắn hơn này:

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

Dù sao, đối với một bố cục như thế này (kích thước cố định và tập trung ở chế độ xem cha mẹ), sẽ đơn giản hơn khi sử dụng mặt nạ tự động hóa và để hệ thống chuyển mặt nạ thành các ràng buộc:

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)

Lưu ý rằng sử dụng tự động hóa là hoàn toàn hợp pháp ngay cả khi bạn cũng đang sử dụng tự động thanh toán. (UIKit vẫn sử dụng tự động hóa ở nhiều nơi trong nội bộ.) Vấn đề là rất khó áp dụng các ràng buộc bổ sung cho chế độ xem đang sử dụng tự động hóa.


Nếu UIKit sử dụng tự động hóa nội bộ thì điều đó có thể giải thích cho hành vi sai trái của các ràng buộc được neo trong trung tâm không? Khi tôi tổ chức một tập hợp các UIButton dưới dạng một lớp con của UIview, các ràng buộc neo dường như hoạt động nhưng chúng không hoạt động khi tôi tổ chức chúng dưới dạng các hàm trong một trình điều khiển khung nhìn. Nếu bạn có thể dành thời gian các bạn có thể có một cái nhìn vào bài đăng này [ stackoverflow.com/questions/40650951/... ler-ta-không thể-thực-add-bất kỳ-new-hàng rào-do]
Greg

Không, điều đó không giải thích được hành vi sai của mã của bạn.
cướp mayoff

12

Về cơ bản nó bao gồm 3 bước

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

Điều này đặt nhãn "xin chào thế giới" ở giữa màn hình.

Vui lòng tham khảo liên kết ràng buộc Tự động thanh toán theo chương trình


9

Đã cập nhật cho 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
 }
}

nhập mô tả hình ảnh ở đây

Loại ràng buộc

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

Đừng quên thêm, youViewName.translatesAutoresizingMaskIntoConstraint = false
iAj

6

Bố cục tự động được thực hiện bằng cách áp dụng các ràng buộc trên hình ảnh. Sử dụng NSLayoutConstraint. Có thể thực hiện một thiết kế lý tưởng và đẹp mắt trên tất cả các thiết bị. Vui lòng thử mã dưới đây.

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

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


4

nó khác một chút trong xcode 7.3.1. đây là những gì tôi nghĩ ra

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

dịchAutoresizingMaskIntoConstraint = false :))
Marin

4

Muốn thêm một số khái niệm lý thuyết vào câu trả lời của Imanou Petit, để người ta có thể hiểu cách thức bố trí tự động hoạt động.

Để hiểu cách bố trí tự động, hãy xem chế độ xem của bạn dưới dạng đối tượng cao su được thu nhỏ ban đầu.

Để đặt một đối tượng trên màn hình, chúng ta cần 4 điều bắt buộc:

  • Tọa độ X của vật (vị trí nằm ngang).

  • Tọa độ Y của vật (vị trí thẳng đứng)

  • Chiều rộng của đối tượng

  • Chiều cao của vật thể.

Tọa độ 1 X: Có nhiều cách cho tọa độ x cho một khung nhìn.

Chẳng hạn như ràng buộc hàng đầu, ràng buộc Trailing, trung tâm theo chiều ngang, vv

Tọa độ 2 Y: Có nhiều cách cho tọa độ y cho một chế độ xem:

Chẳng hạn như ràng buộc trên, ràng buộc dưới, trung tâm dọc, vv

3 Chiều rộng của đối tượng: Có hai cách đưa ra giới hạn độ rộng cho một khung nhìn:

a. Thêm ràng buộc chiều rộng cố định (coi ràng buộc này là thanh sắt có chiều rộng cố định và bạn đã móc đối tượng cao su của mình theo chiều ngang với nó để đối tượng cao su không co lại hoặc giãn ra)

b. Không thêm bất kỳ ràng buộc về chiều rộng nào nhưng thêm ràng buộc tọa độ x vào cả hai đầu theo dõi và dẫn, hai ràng buộc này sẽ mở rộng / thu hẹp đối tượng cao su của bạn bằng cách kéo / đẩy nó từ cả hai đầu, dẫn và theo dõi.

4 Chiều cao của đối tượng: Tương tự như chiều rộng, có hai cách đưa ra giới hạn chiều cao cho chế độ xem:

a. Thêm ràng buộc về chiều cao cố định (coi ràng buộc này là thanh sắt có chiều cao cố định và bạn đã móc đối tượng cao su của mình theo chiều dọc với nó để đối tượng cao su không co lại hoặc giãn ra)

b. Không thêm bất kỳ ràng buộc về chiều cao nào nhưng thêm ràng buộc tọa độ x vào cả hai đầu của chế độ xem trên và dưới, hai ràng buộc này sẽ mở rộng / thu hẹp đối tượng cao su của bạn kéo / đẩy nó từ cả hai đầu, trên và dưới.


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

7
Vui lòng giải thích mã và cách nó trả lời câu hỏi.
Ben Rhys-Lewis

3

Đây là một cách để thêm các ràng buộc theo chương trình

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

nhập mô tả hình ảnh ở đây


2

Bạn đang thêm tất cả các ràng buộc được xác định self.viewlà sai, vì các ràng buộc về chiều rộng và chiều cao nên được thêm vàonewView .

Ngoài ra, theo tôi hiểu, bạn muốn đặt chiều rộng và chiều cao không đổi 100: 100. Trong trường hợp này, bạn nên thay đổi mã của mình thành:

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)

2

Nếu bạn thấy ở trên là xấu xí. Bạn nên cân nhắc sử dụng DSL cho các ràng buộc. Chẳng hạn như SnapKit làm cho API ràng buộc thân thiện hơn nhiều

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

1

Chúng ta có thể dễ dàng làm điều này với trong swift 5.1

thiết lập 1

  • căn chỉnh để xem trung tâm
  • chiều cao khung nhìn phụ được đặt bằng float

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

thiết lập 2

  • căn chỉnh để xem neo hàng đầu và hàng đầu
  • chiều rộng khung nhìn được đặt bằng chiều cao chiều rộng khung nhìn

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

Kết quả


0

Hãy thử UIViewmở rộng thanh lịch này cho các ràng buộc. Bạn có thể thực hiện các ràng buộc dễ dàng như:


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

Đây là phần mở rộng, chỉ cần sao chép nó vào dự án của bạn.

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
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.