Search code examples
iosswift2constraintsnslayoutconstraintprogrammatically-created

Programmatically Setting Constraints Causes Conflict in Swift


As i posted in this GitHub issue, I am having trouble with some hidden constraints that throw an error whenever I try to add my own constraints

2016-04-18 19:22:04.270 Metric Time[1519:447809] 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)
(
"<NSAutoresizingMaskLayoutConstraint:0x15e670e70 h=--& v=--& Metric_Time.View:0x15e692e70.midX == + 115>",
"<NSLayoutConstraint:0x15e5048c0 Metric_Time.View:0x15e692e70.centerX == UIView:0x15e6953e0.centerX>",
"<NSAutoresizingMaskLayoutConstraint:0x15e55fd30 h=-&- v=-&- 'UIView-Encapsulated-Layout-Left' H:|-(0)-[UIView:0x15e6953e0]   (Names: '|':UIWindow:0x15e688ed0 )>",
"<NSLayoutConstraint:0x15e54e750 'UIView-Encapsulated-Layout-Width' H:[UIView:0x15e6953e0(320)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x15e5048c0 Metric_Time.View:0x15e692e70.centerX == UIView:0x15e6953e0.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.`

I have tried looking for the places that these constraints could have been created, but searching my ViewController.swift file for keywords such as constraint, layout .etc turned up only the code that I wrote.

My code is all on GitHub if anyone wants to mess around with it.


Solution

  • If you are going to add constraints programmatically, you need to turn off translateAutoresizingMaskIntoConstraints. You also don't have enough constraints to satisfy the layout engine. Remember that UIView's don't have an intrinsic size and if you are using auto layout with a view you need to set everything with constraints and not rely on a mixture of constraints and frames. one possible solution is to add some code like:

            self.view.addSubview(clockView)
            clockView.translatesAutoresizingMaskIntoConstraints = false
            clockView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: 0.0).active = true
            clockView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor, constant: 0.0).active = true
            clockView.widthAnchor.constraintEqualToConstant(230.0).active = true
            clockView.heightAnchor.constraintEqualToConstant(230.0).active = true
    

    However this is not exactly what you want as when it is in landscape your clock overlays your label. But you could fix that by playing with clockView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: 0.0).active = true