对于 ViewController 的 'main' 视图,是否必须将 translatesAutoresizingMaskIntoConstraints 设置为 false?
Do you have to set translatesAutoresizingMaskIntoConstraints to false for a ViewController's 'main' view?
我在 Xcode 中有一个空白的 Swift 项目,我没有使用故事板。我有一个观点,我已经在 viewDidLoad:
下的代码中添加了
var view1 = UIView()
view1.backgroundColor = .red
view.addSubview(view1)
view1.translatesAutoresizingMaskIntoConstraints = false
然后我添加约束:
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
view1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
view1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
view1.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
])
视图加载并在模拟器中看起来很好。但是我在另一个项目中遇到了一些其他视图的问题,所以我构建了上面的内容进行测试。所以我发现即使上面的构建和工作,如果我使用以下方法检查不明确的布局:
print(view1.hasAmbiguousLayout)
我记录了错误:
2021-02-14 15:26:34.919048+1100 autolayoutextensions[6603:4438601]
[LayoutConstraints] View has an ambiguous layout. See "Auto Layout
Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from
invoking -[UIView _autolayoutTrace] to provide additional detail.
*UIView:0x13360c3b0- AMBIGUOUS LAYOUT for UIView:0x13360c3b0.Width{id: 9}, UIView:0x13360c3b0.Height{id: 12}
Legend: * - is laid out with auto layout + - is laid out manually,
but is represented in the layout engine because
translatesAutoresizingMaskIntoConstraints = YES • - layout engine
host true
让这些错误不被记录的唯一方法是同时设置 ViewController 的主视图,如下所示:
view.translatesAutoresizingMaskIntoConstraints = false
通过这样做,我知道得到以下日志输出:
false
所以我的问题是...我没有在 Apple 的文档(或此处,谷歌搜索等)中读到任何地方说您必须将 viewController 的 view.translatesAutoresizingMaskIntoConstraints
设置为 false
。我错过了什么吗?抱歉,如果这只是我的理解,但最好能澄清一下。
首先,你不应该在视图控制器的主视图上设置 .translatesAutoresizingMaskIntoConstraints = false
(除非你将控制器加载为 child,但这不是你在问题中谈论的内容) .
您需要 read-up 查看 / view-controller life-cycle.
在 viewDidLoad()
中,auto-layout 尚未 运行 管理视图和子视图布局。
在 viewDidLayoutSubview()
、auto-layout HAS 运行 中,但这可能取决于您的设计的动态程度(除其他因素外)调用不止一次。
在 viewDidAppear()
中,所有布局都已完成(除非您的代码正在 运行 对动画视图进行异步处理,添加其他视图,等等)。
所以,试试 运行 这个简单的例子 - 它会打印当前正在执行的函数的名称以及 .hasAmbiguousLayout
:
的输出
class TestLayoutViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var view1 = UIView()
view1.backgroundColor = .red
view.addSubview(view1)
view1.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
view1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
view1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
view1.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
])
print() // blank line
print(#function)
print() // blank line
print("In viewDidLoad(), does subview have ambigous layout?")
print(view1.hasAmbiguousLayout)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let v = view.subviews.first else {
return
}
print() // blank line
print(#function)
print() // blank line
print("In viewDidLayoutSubviews(), does subview have ambigous layout?")
print(v.hasAmbiguousLayout)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
guard let v = view.subviews.first else {
return
}
print() // blank line
print(#function)
print() // blank line
print("In viewDidAppear(), does subview have ambigous layout?")
print(v.hasAmbiguousLayout)
}
}
这是您应该在调试控制台中看到的内容:
viewDidLoad()
In viewDidLoad(), does subview have ambigous layout?
2021-02-14 08:41:46.694337-0500 PanZoom[43869:6978294] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
*UIView:0x7fd472604960- AMBIGUOUS LAYOUT for UIView:0x7fd472604960.Width{id: 90}, UIView:0x7fd472604960.Height{id: 93}
Legend:
* - is laid out with auto layout
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
• - layout engine host
true
viewDidLayoutSubviews()
In viewDidLayoutSubviews(), does subview have ambigous layout?
false
viewDidAppear(_:)
In viewDidAppear(), does subview have ambigous layout?
false
如您所见,在 viewDidLoad()
期间我们得到 auto-layout 歧义,但 NOT 在 viewDidLayoutSubviews()
或 viewDidAppear()
.
我在 Xcode 中有一个空白的 Swift 项目,我没有使用故事板。我有一个观点,我已经在 viewDidLoad:
下的代码中添加了var view1 = UIView()
view1.backgroundColor = .red
view.addSubview(view1)
view1.translatesAutoresizingMaskIntoConstraints = false
然后我添加约束:
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
view1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
view1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
view1.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
])
视图加载并在模拟器中看起来很好。但是我在另一个项目中遇到了一些其他视图的问题,所以我构建了上面的内容进行测试。所以我发现即使上面的构建和工作,如果我使用以下方法检查不明确的布局:
print(view1.hasAmbiguousLayout)
我记录了错误:
2021-02-14 15:26:34.919048+1100 autolayoutextensions[6603:4438601] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
*UIView:0x13360c3b0- AMBIGUOUS LAYOUT for UIView:0x13360c3b0.Width{id: 9}, UIView:0x13360c3b0.Height{id: 12}
Legend: * - is laid out with auto layout + - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES • - layout engine host true
让这些错误不被记录的唯一方法是同时设置 ViewController 的主视图,如下所示:
view.translatesAutoresizingMaskIntoConstraints = false
通过这样做,我知道得到以下日志输出:
false
所以我的问题是...我没有在 Apple 的文档(或此处,谷歌搜索等)中读到任何地方说您必须将 viewController 的 view.translatesAutoresizingMaskIntoConstraints
设置为 false
。我错过了什么吗?抱歉,如果这只是我的理解,但最好能澄清一下。
首先,你不应该在视图控制器的主视图上设置 .translatesAutoresizingMaskIntoConstraints = false
(除非你将控制器加载为 child,但这不是你在问题中谈论的内容) .
您需要 read-up 查看 / view-controller life-cycle.
在 viewDidLoad()
中,auto-layout 尚未 运行 管理视图和子视图布局。
在 viewDidLayoutSubview()
、auto-layout HAS 运行 中,但这可能取决于您的设计的动态程度(除其他因素外)调用不止一次。
在 viewDidAppear()
中,所有布局都已完成(除非您的代码正在 运行 对动画视图进行异步处理,添加其他视图,等等)。
所以,试试 运行 这个简单的例子 - 它会打印当前正在执行的函数的名称以及 .hasAmbiguousLayout
:
class TestLayoutViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var view1 = UIView()
view1.backgroundColor = .red
view.addSubview(view1)
view1.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
view1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
view1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
view1.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
])
print() // blank line
print(#function)
print() // blank line
print("In viewDidLoad(), does subview have ambigous layout?")
print(view1.hasAmbiguousLayout)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let v = view.subviews.first else {
return
}
print() // blank line
print(#function)
print() // blank line
print("In viewDidLayoutSubviews(), does subview have ambigous layout?")
print(v.hasAmbiguousLayout)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
guard let v = view.subviews.first else {
return
}
print() // blank line
print(#function)
print() // blank line
print("In viewDidAppear(), does subview have ambigous layout?")
print(v.hasAmbiguousLayout)
}
}
这是您应该在调试控制台中看到的内容:
viewDidLoad()
In viewDidLoad(), does subview have ambigous layout?
2021-02-14 08:41:46.694337-0500 PanZoom[43869:6978294] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
*UIView:0x7fd472604960- AMBIGUOUS LAYOUT for UIView:0x7fd472604960.Width{id: 90}, UIView:0x7fd472604960.Height{id: 93}
Legend:
* - is laid out with auto layout
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
• - layout engine host
true
viewDidLayoutSubviews()
In viewDidLayoutSubviews(), does subview have ambigous layout?
false
viewDidAppear(_:)
In viewDidAppear(), does subview have ambigous layout?
false
如您所见,在 viewDidLoad()
期间我们得到 auto-layout 歧义,但 NOT 在 viewDidLayoutSubviews()
或 viewDidAppear()
.