以编程方式自动布局不起作用
Posted
技术标签:
【中文标题】以编程方式自动布局不起作用【英文标题】:Autolayout programmatically doesn't work 【发布时间】:2014-10-27 14:04:33 【问题描述】:我想以编程方式将 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 上的 UIConstraintBasedLayoutDebugging 类别中的方法也可能会有所帮助。
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 上的 UIConstraintBasedLayoutDebugging 类别中的方法也可能会有所帮助。
(这里很难有一个好的布局;))
我不明白为什么这些约束不起作用,它们似乎与情节提要中的相同
【问题讨论】:
(注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档) 解决方案就在日志中。 UIScrollView doesn't use autolayout constraints 的可能重复项 尝试调用transitionImageView.setTranslatesAutoresizingMask(false) 【参考方案1】:更新到 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)
否则UIImageView
将是UIImage
的大小,即使您分配了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
【讨论】:
以上是关于以编程方式自动布局不起作用的主要内容,如果未能解决你的问题,请参考以下文章