使用自动布局检索子视图的正确位置 [英] Retrieve the right position of a subView with auto-layout

查看:111
本文介绍了使用自动布局检索子视图的正确位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以编程方式将视图放置在情节提要中创建的所有子视图的中心.

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)

转换时,必须从视图原始坐标转换,这里是horizo​​ntalSv

When you convert, you have to convert from the view original coordinates, here it was the horizontalSv

这篇关于使用自动布局检索子视图的正确位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆