为什么布局引擎会在此示例中启动?

时间:2017-05-31 08:11:10

标签: ios swift autolayout uikit

我创建了一个只有两个视图的Playground项目:一个标签位于屏幕中央,一个按钮贴在屏幕下方。当我发布这个例子时,一切都运行得很好。

但是只要我在Label视图中添加Layout Constraint,Button按钮就会跳转到屏幕顶部!

Nota Bene:我在两个视图上使用translateAutoresizingMaskIntoConstraints = false

以下是没有约束的代码:

//: Playground - noun: a place where people can play

import UIKit
import PlaygroundSupport

let liveview = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 600))

let button = UIButton(frame: CGRect(x: 123.5, y: 566, width: 50, height: 50))
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("BUTTON", for: .normal)
button.backgroundColor = UIColor.darkGray
button.sizeToFit()
liveview.addSubview(button)

let label = UILabel(frame: CGRect(x: 134.75, y: 289.75, width: 50, height: 50))
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.blue
label.text = "LABEL"
label.sizeToFit()
liveview.addSubview(label)

PlaygroundPage.current.liveView = liveview

这是结果。这是预期的,还没有限制。请注意Button视图的位置:它位于屏幕的底部。

First Screenshot - no constraints applied

现在我正在为标签视图添加约束。这种添加的结果是按钮视图跳到屏幕顶部!这是相应的代码,结果如下:

//: Playground - noun: a place where people can play

import UIKit
import PlaygroundSupport

let liveview = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 600))

let button = UIButton(frame: CGRect(x: 123.5, y: 566, width: 50, height: 50))
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("BUTTON", for: .normal)
button.backgroundColor = UIColor.darkGray
button.sizeToFit()
liveview.addSubview(button)

let label = UILabel(frame: CGRect(x: 134.75, y: 289.75, width: 50, height: 50))
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.blue
label.text = "LABEL"
label.sizeToFit()
liveview.addSubview(label)

NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal, toItem: liveview, attribute: .centerX, multiplier: 1.0, constant: 0.0).isActive = true

print(liveview.constraints)

PlaygroundPage.current.liveView = liveview

Second Screenshot - the label constraint is applied

如果您感兴趣,可以在此处打印约束列表,确认按钮视图没有相关约束:

[<NSLayoutConstraint:0x60000008d890 UILabel:0x7fc2c3f06c20'LABEL'.centerX == UIView:0x7fc2c3d030c0.centerX   (active)>]

我的问题如下:为什么布局引擎移动视图而没有相关的约束。

1 个答案:

答案 0 :(得分:1)

translateAutoresizingMaskIntoConstraints = false告诉自动布局不要将您的视图frame转换为约束,因此您的UIButton没有任何限制。您的UIButton受到限制,自动布局可以将其放在最佳位置。通常这意味着0的水平和垂直偏移。

在您的第一个示例中,UIButtonUILabel都不受约束,并且由于根本没有约束,布局引擎无法运行。

在第二个示例中,只要向UILabel添加约束,布局引擎就会启动并开始放置内容。请注意,它会按照您的要求对您的标签进行居中,但它也会将其移动到屏幕顶部,因为未指定垂直位置。然后,它将您的按钮移动到水平偏移0和垂直偏移0。同样,由于您的按钮没有约束,自动布局可随意移动到任何地方。

如果您喜欢将按钮放在框架上的按钮,则只需设置translateAutoresizingMaskIntoContraints = false即可。将其设置为true

对于您的标签,一旦开始给予它约束的路径,您应该确保它已完全指定。如果您希望将标签设置为与其内在值不同的值,请为标签指定垂直约束,宽度和高度约束。

另请注意,通过设置isActive = true激活约束时,约束会添加到相应的视图中。如果您要将 height width 约束添加到按钮,则这些约束将添加到button.constraints而不会添加到liveview.contraints。如果要创建一个约束,使按钮的宽度等于标签的宽度,那么这个约束将被添加到它们共同的祖先约束中。