Swift - 将 NSLayoutConstraint 添加到我的按钮

Swift - Add NSLayoutConstraint to my Button

我想在底部和左右角始终有一个按钮。 我想通过以编程方式向我的按钮添加约束来做到这一点。 我的代码:

class LoginController: UIViewController {

    @IBOutlet weak var LoginButton: UIButton!

    override func loadView() {

        super.loadView()

        //Button Height Constraint
        let constraintButtonPlayWidth = NSLayoutConstraint (item: self.LoginButton,
            attribute: NSLayoutAttribute.Height,
            relatedBy: NSLayoutRelation.Equal,
            toItem: nil,
            attribute: NSLayoutAttribute.NotAnAttribute,
            multiplier: 1,
            constant: 80)
        self.view.addConstraint(constraintButtonPlayWidth)

        //Button Right Constraint
        let r = NSLayoutConstraint(item: self.LoginButton, attribute: .Right,
            relatedBy: .Equal, toItem: self.view, attribute: .Right, multiplier: 1.0, constant: 0.0)

        //Button Left Constraint
        let l = NSLayoutConstraint(item: self.LoginButton, attribute: .Left,
            relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1.0, constant: 100.0)

        //Button Bottom Constraint
        let b = NSLayoutConstraint(item: self.LoginButton, attribute: .Bottom,
            relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 100.0)

        self.view.addConstraints([l,b,r])

当我运行这段代码时:


当我在设计器中添加约束时:

当我 运行 应用程序运行时

我的问题:我的错误是什么?

如果您想要按钮位于设置约束的底部,请删除常量 100。

let b = NSLayoutConstraint(item: self.button, attribute: .Bottom,
            relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 0.0)

如果您的目标是 iOS 9,您还可以像这样添加约束条件:

button.addConstraint(button.heightAnchor.constraintEqualToConstant(80))
        self.view.addConstraint(self.view.leadingAnchor.constraintEqualToAnchor(button.leadingAnchor))
        self.view.addConstraint(self.view.trailingAnchor.constraintEqualToAnchor(button.trailingAnchor))
        self.view.addConstraint(self.view.bottomAnchor.constraintEqualToAnchor(button.bottomAnchor))

如果故事板中的视图没有约束,Interface Builder 会自动生成一些约束。这些自动生成的约束将与代码生成的约束冲突。

所以,在我看来你有四个选择。

  1. 在代码中生成按钮:

  2. 在 Interface Builder 中创建约束并在构建时通过在 Interface Builder 中选择约束并选中 "Remove at build time"

  3. 来删除它们
  4. 删除代码中自动生成的约束

  5. 在界面生成器中创建约束

选项 1 - 在代码中生成按钮

override func viewDidLoad()
{
    super.viewDidLoad()
    let button = UIButton()
    button.setTitle("Login", forState: UIControlState.Normal)
    button.backgroundColor = UIColor.redColor()
    button.translatesAutoresizingMaskIntoConstraints = false

    self.view.addSubview(button)

    let heightConstraint = NSLayoutConstraint(
        item: button,
        attribute: NSLayoutAttribute.Height,
        relatedBy: NSLayoutRelation.Equal,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 1.0,
        constant: 80
    )
    button.addConstraint(heightConstraint)

    let leftConstraint = NSLayoutConstraint(
        item: button,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Leading,
        multiplier: 1.0,
        constant: 0
    )
    self.view.addConstraint(leftConstraint)

    let rightConstraint = NSLayoutConstraint(
        item: button,
        attribute: NSLayoutAttribute.Trailing,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Trailing,
        multiplier: 1.0,
        constant: 0
    )
    self.view.addConstraint(rightConstraint)

    let topConstraint = NSLayoutConstraint(
        item: button,
        attribute: NSLayoutAttribute.Bottom,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Bottom,
        multiplier: 1,
        constant: 0
    )
    self.view.addConstraint(topConstraint)
}

选项 2 - 代码中的约束(在构建时删除了 IB 中的约束)

创建至少一个约束(例如登录按钮上的高度约束)并设置“在构建时删除”复选框。之后你会得到故事板错误,你可以通过添加更多约束来修复它们(但我认为修复故事板错误并不是真的必要)

override func viewDidLoad()
{
    super.viewDidLoad()

    self.LoginButton.translatesAutoresizingMaskIntoConstraints = false

    let heightConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Height,
        relatedBy: NSLayoutRelation.Equal,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 1.0,
        constant: 80
    )
    self.LoginButton.addConstraint(heightConstraint)

    let leftConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Leading,
        multiplier: 1.0,
        constant: 0
    )
    self.view.addConstraint(leftConstraint)

    let rightConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Trailing,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Trailing,
        multiplier: 1.0,
        constant: 0
    )
    self.view.addConstraint(rightConstraint)

    let topConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Bottom,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Bottom,
        multiplier: 1,
        constant: 0
    )
    self.view.addConstraint(topConstraint)
}

选项 3 - 删除代码中自动生成的约束

override func viewDidLoad()
{
    super.viewDidLoad()

    var removeConstraints : [NSLayoutConstraint] = []
    for constraint in self.view.constraints
    {
        if constraint.firstItem === self.LoginButton
        {
            removeConstraints.append(constraint)
        }
    }

    self.view.removeConstraints(removeConstraints)

    self.LoginButton.removeConstraints(self.LoginButton.constraints)
    self.LoginButton.translatesAutoresizingMaskIntoConstraints = false

    let heightConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Height,
        relatedBy: NSLayoutRelation.Equal,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 1.0,
        constant: 80
    )
    self.LoginButton.addConstraint(heightConstraint)

    let leftConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Leading,
        multiplier: 1.0,
        constant: 0
    )
    self.view.addConstraint(leftConstraint)

    let rightConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Trailing,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Trailing,
        multiplier: 1.0,
        constant: 0
    )
    self.view.addConstraint(rightConstraint)

    let topConstraint = NSLayoutConstraint(
        item: self.LoginButton,
        attribute: NSLayoutAttribute.Bottom,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Bottom,
        multiplier: 1,
        constant: 0
    )
    self.view.addConstraint(topConstraint)
}

选项 4 - 在 Interface Builder 中创建

在 Interface Builder 中创建约束