使用自动布局检索子视图的正确位置 [英] Retrieve the right position of a subView with auto-layout
问题描述
我想以编程方式将视图放置在情节提要中创建的所有子视图的中心.
I want to place programmatically a view at the center of all the the subviews created in a storyboard.
在情节提要中,我有一个视图,并且在Vertical StackView内,该视图具有填充整个屏幕的约束,分布为等间距". 在垂直堆栈视图"内部,我有3个水平堆栈视图,约束高度= 100,尾随前导空间为0(超级视图中).分布也是等间距". 在每个水平堆栈视图中,我有两个视图,约束宽度和高度= 100,这些视图是红色的.
In the storyboard, I have a view, and inside a Vertical StackView, which has constraint to fill the full screen, distribution "Equal spacing". Inside of the Vertical Stack View, I have 3 horizontal stack views, with constraint height = 100, and trailing and leading space : 0 from superview. The distribution is "equal spacing" too. In each horizontal stack view, I have two views, with constraint width and height = 100, that views are red.
到目前为止,太好了,我有了想要的界面,
So far, so good, I have the interface I wanted,
现在我想获取每个红色视图的中心,以在该位置放置另一个视图(实际上,它将是棋盘上方的一个棋子...)
Now I want to retrieve the center of each red view, to place another view at that position (in fact, it'll be a pawn over a checkboard...)
所以我写了:
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中再次更改位置.
With that, I can see that in ViewDidLoad and ViewWillAppear, the metrics are those of the storyboard. The positions changed then in viewWillLayoutSubviews, in viewDidLayoutSubviews and again in viewDidAppear.
在viewDidAppear之后(因此在所有视图都放置好之后),我必须将x坐标除以2,并添加类似35的值(请参见代码),以使新的黑色视图正确地位于红色视图的中心.我不明白为什么我不能简单地使用红色视图的中心...为什么它可以用于y位置?
After viewDidAppear (so after all the views are in place), I have to divide x coordinate by 2 and adding something like 35 (see code) to have the new black view correctly centered in the red view. I don't understand why I can't simply use the center of the red view... And why does it works for y position ?
推荐答案
我发现了您的问题,请替换
I found your issue, replace
let redCenter = redView.convert(redView.center, to:self.view)
使用
let redCenter = horizontalSV.convert(redView.center, to: self.view)
转换时,必须从视图原始坐标转换,这里是horizontalSv
When you convert, you have to convert from the view original coordinates, here it was the horizontalSv
这篇关于使用自动布局检索子视图的正确位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!