Autolayout以编程方式不起作用

时间:2014-10-27 14:04:34

标签: ios swift nsautolayout

我想以编程方式将UIImageView添加到视图中,并添加约束以使其垂直和水平居中。 使用故事板它可以工作,但不能以编程方式工作。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        var transitionImageView = UIImageView()
        transitionImageView.frame.size = CGSize(width: 60, height: 68)
        transitionImageView.contentMode = UIViewContentMode.ScaleToFill

        var transitionImage = UIImage(named: "SoProxyLogo60pt")
        transitionImageView.image = transitionImage
        self.view.addSubview(transitionImageView)

        // Position
        let transitionImageViewConstraintCenterX = NSLayoutConstraint(item: transitionImageView, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 0)
        transitionImageViewConstraintCenterX.identifier = "Transition Image View Constraint Center X"
        let transitionImageViewConstraintCenterY = NSLayoutConstraint(item: transitionImageView, attribute: .CenterY, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1, constant: 0)
        transitionImageViewConstraintCenterY.identifier = "Transition Image View Constraint Center Y"

        self.view.addConstraint(transitionImageViewConstraintCenterX)
        self.view.addConstraint(transitionImageViewConstraintCenterY)        
    }
}

我遇到了这些错误:

  

2014-10-27 14:45:18.420 transitionTest1 [3438:70b]无法同时满足约束条件。      可能至少下列列表中的一个约束是您不想要的约束。试试这个:(1)看看每个约束并试着找出你不期望的东西; (2)找到添加了不需要的约束或约束的代码并修复它。 (注意:如果你看到你不理解的NSAutoresizingMaskLayoutConstraints,请参阅UIView属性的文档translatesAutoresizingMaskIntoConstraints)

<NSLayoutConstraint:0x7fbb5b210790 'Transition Image View Constraint Center X' UIImageView:0x7fbb5af682d0.centerX == UIView:0x7fbb5af674f0.centerX>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b25eee0 h=--& v=--& UIImageView:0x7fbb5af682d0.midX == + 30>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b258ee0 h=-&- v=-&- UIView:0x7fbb5af674f0.width == UIViewControllerWrapperView:0x7fbb5b257e20.width>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b260840 h=-&- v=-&- UIViewControllerWrapperView:0x7fbb5b257e20.width == UINavigationTransitionView:0x7fbb5af5b020.width>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b2612b0 h=-&- v=-&- UINavigationTransitionView:0x7fbb5af5b020.width == UILayoutContainerView:0x7fbb5af2adf0.width>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b261d40 h=-&- v=-&- UILayoutContainerView:0x7fbb5af2adf0.width == UIWindow:0x7fbb5b251ba0.width>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b25ff30 h=--- v=--- H:[UIWindow:0x7fbb5b251ba0(320)]>
  

将尝试通过违反约束来恢复   

     

中断objc_exception_throw以在调试器中捕获它。   UIView中列出的UIVonstraintBasedLayoutDebugging类别中的方法也可能有所帮助。

     

2014-10-27 14:45:18.421 transitionTest1 [3438:70b]无法同时满足约束条件。      可能至少下列列表中的一个约束是您不想要的约束。试试这个:(1)看看每个约束并试着找出你不期望的东西; (2)找到添加了不需要的约束或约束的代码并修复它。 (注意:如果你看到你不理解的NSAutoresizingMaskLayoutConstraints,请参阅UIView属性的文档translatesAutoresizingMaskIntoConstraints)

<NSLayoutConstraint:0x7fbb5b252fd0 'Transition Image View Constraint Center Y' UIImageView:0x7fbb5af682d0.centerY == UIView:0x7fbb5af674f0.centerY>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b25f140 h=--& v=--& UIImageView:0x7fbb5af682d0.midY == + 34>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b258f80 h=-&- v=-&- UIView:0x7fbb5af674f0.height == UIViewControllerWrapperView:0x7fbb5b257e20.height>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b260930 h=-&- v=-&- UIViewControllerWrapperView:0x7fbb5b257e20.height == UINavigationTransitionView:0x7fbb5af5b020.height>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b2613b0 h=-&- v=-&- UINavigationTransitionView:0x7fbb5af5b020.height == UILayoutContainerView:0x7fbb5af2adf0.height>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b261e30 h=-&- v=-&- UILayoutContainerView:0x7fbb5af2adf0.height == UIWindow:0x7fbb5b251ba0.height>,
<NSAutoresizingMaskLayoutConstraint:0x7fbb5b262730 h=--- v=--- V:[UIWindow:0x7fbb5b251ba0(480)]>
  

将尝试通过违反约束来恢复   

     

中断objc_exception_throw以在调试器中捕获它。   UIView中列出的UIVonstraintBasedLayoutDebugging类别中的方法也可能有所帮助。

(这里很难有好的布局;))

我不明白为什么这些约束不起作用,它们似乎与故事板中的那些相同

1 个答案:

答案 0 :(得分:3)

更新SWIFT 3

我测试了你的代码,我发现的问题是你错过了这一行:

transitionImageView.translatesAutoresizingMaskIntoConstraints = false

此外,如果您希望图像尺寸为60x68,则需要为宽度和高度添加一些约束,如下所示:

let constW = NSLayoutConstraint(item: transitionImageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 60)

let constV = NSLayoutConstraint(item: transitionImageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 68)

并将其添加到您的UIImageView

transitionImageView.addConstraint(constW)
transitionImageView.addConstraint(constV)

否则即使您指定UIImageViewUIImage也会是CGSize大小(因为setTranslatesAutoresizingMaskIntoConstraints(false)会停用您指定的CGSize

所以你的viewDidLoad()方法可能是这样的:

override func viewDidLoad() {
    super.viewDidLoad()
    let transitionImageView = UIImageView()
    transitionImageView.contentMode = UIViewContentMode.scaleToFill

    //Don't forget this line
    transitionImageView.translatesAutoresizingMaskIntoConstraints = false

    let transitionImage = UIImage(named: "SoProxyLogo60pt.jpg")
    transitionImageView.image = transitionImage
    self.view.addSubview(transitionImageView)

    // Position
    let transitionImageViewConstraintCenterX = NSLayoutConstraint(item: transitionImageView, attribute: .centerX, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1, constant: 0)
    transitionImageViewConstraintCenterX.identifier = "Transition Image View Constraint Center X"
    let transitionImageViewConstraintCenterY = NSLayoutConstraint(item: transitionImageView, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1, constant: 0)
    transitionImageViewConstraintCenterY.identifier = "Transition Image View Constraint Center Y"

    let constW = NSLayoutConstraint(item: transitionImageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 60)

    let constV = NSLayoutConstraint(item: transitionImageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 68)

    self.view.addConstraint(transitionImageViewConstraintCenterX)
    self.view.addConstraint(transitionImageViewConstraintCenterY)
    transitionImageView.addConstraint(constW) //self.view.addConstraint(constW) also works
    transitionImageView.addConstraint(constV) //self.view.addConstraint(constV) also works
}