问题
I want to add programmatically an UIImageView to a view and add constraints to center it, vertically and horizontally. With the storyboard it's works but not programmatically.
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)
}
}
I've got these errors :
2014-10-27 14:45:18.420 transitionTest1[3438:70b] 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: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)]>
Will attempt to recover by breaking constraint
Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.
2014-10-27 14:45:18.421 transitionTest1[3438:70b] 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: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)]>
Will attempt to recover by breaking constraint
Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.
(It's hard to have a good layout here ;) )
I don't understand why these constraints doesn't work, they seem to be the same that those in the storyboard
回答1:
UPDATED TO SWIFT 3
I tested your code and the problem i found was that you missed this line:
transitionImageView.translatesAutoresizingMaskIntoConstraints = false
Also if you want your image size is 60x68 you need to add a couple of constraints for the width and height like this:
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)
and add them to your UIImageView
transitionImageView.addConstraint(constW)
transitionImageView.addConstraint(constV)
Otherwise the UIImageView
will be the UIImage
size even if you assign CGSize
(because setTranslatesAutoresizingMaskIntoConstraints(false)
disables the CGSize
you assigned).
So your viewDidLoad()
method could be like this:
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
}
来源:https://stackoverflow.com/questions/26589335/autolayout-programmatically-doesnt-work