我想以编程方式将视图放置在故事板中创建的所有子视图的中心。
在故事板中,我有一个视图,在一个垂直 StackView 内部,它具有填充全屏的约束,分布“等间距”。
在垂直堆栈视图内部,我有 3 个水平堆栈视图,约束高度 = 100,超级视图的尾随和前导空格:0。分布也是“等间距”。
在每个水平堆栈视图中,我有两个视图,约束宽度和高度 = 100,视图为红色。
So far, so good, I have the interface I wanted,
现在我想检索每个红色视图的中心,在该位置放置另一个视图(事实上,它将是棋盘上的棋子......)
所以我写道:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var verticalStackView:UIStackView?
override func viewDidLoad() {
super.viewDidLoad()
print ("viewDidLoad")
printPos()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print ("viewWillAppear")
printPos()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
print ("viewWillLayoutSubviews")
printPos()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print ("viewDidLayoutSubviews")
printPos()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print ("viewDidAppear")
printPos()
addViews()
}
func printPos() {
guard let verticalSV = verticalStackView else { return }
for horizontalSV in verticalSV.subviews {
for view in horizontalSV.subviews {
let center = view.convert(view.center, to:nil)
print(" - \(center)")
}
}
}
func addViews() {
guard let verticalSV = verticalStackView else { return }
for horizontalSV in verticalSV.subviews {
for redView in horizontalSV.subviews {
let redCenter = redView.convert(redView.center, to:self.view)
let newView = UIView(frame: CGRect(x:0, y:0, width:50, height:50))
//newView.center = redCenter
newView.center.x = 35 + redCenter.x / 2
newView.center.y = redCenter.y
newView.backgroundColor = .black
self.view.addSubview(newView)
}
}
}
}
这样,我可以看到在 ViewDidLoad 和 ViewWillAppear 中,指标是故事板的指标。然后,位置在 viewWillLayoutSubviews、viewDidLayoutSubviews 和 viewDidAppear 中发生变化。
在 viewDidAppear 之后(所以在所有视图都就位之后),我必须将 x 坐标除以 2 并添加类似 35 的值(参见代码)以使新的黑色视图正确居中于红色视图的中心。我不明白为什么我不能简单地使用红色视图的中心......为什么它适用于 y 位置?