如果初始帧配置错误,如何在使用自动布局时获取 UIView 的 (x, y)?



也许这是我的设置代码对UIViewframe属性的滥用,对于自动布局视图,其中,因为我假设视图的初始frame属性值一旦添加了自动布局约束就不重要了,我可以使用frame.origin来缓存在坐标空间中不是真正视图原点的值。

我所说的"滥用"是什么意思?我将frame.origin设置为约束设置函数调用中的参数值,因为我喜欢在我的代码中通过CGRect调整约束偏移的简洁性和便利性。但也许适得其反?不知道为什么……

例如:

let view = UIView(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
NSLayoutConstraint.activate([
view.leadingAnchor.constraint(equalTo: leftSideView.trailingAnchor, 
constant: view.frame.origin.x)
.
.
.
])

最初看起来很好,视图按预期放置在屏幕上,但在视图被AutoLayout布局后,frame.origin似乎反映了我最初的盗用…例如,在自动布局之后,frame.origin仍然是(10,10)…反正在AutoLayout之后,frame.origin都是不是在坐标系中的正确绝对值一般指的是frame属性来获取。

我这样做之后:

view.setNeedLayout()
view.layoutIfNeeded()

当我打印框架时。原点值,它们不是视图的实际位置。

为什么不呢?那么,我怎样才能找到正确的值呢?

也许我需要调用一个UIView的父视图坐标转换函数?

UPDATE:没有其原点集的视图实际上是leftSideView,我使用与我约束的视图相同的方法配置。我确实运行setNeedsLayout()/layout,但现在我认为自动布局还没有足够的数据来计算帧,所以我有一个先有蛋的问题,我试图添加基于约束的约束尚未解决,这将不起作用

您正在要求错误的视图布局。view没有太多的布局,除了它自己的大小。它不知道如何布局自己相对于leftSideView,因为leftSideView不是它的子视图之一。

布局view相对于leftSideView,找到他们共同的父,并要求布局。假设view.superview是共同的父节点,执行:

view.superview!.layoutIfNeeded()

那么view.frame将是您期望的值。

或者,您可以在您想要布局的视图的公共父视图的UIViewControllerlayoutSubviews中覆盖viewDidLayoutSubviews,以检测布局何时完成,而无需调用layoutIfNeeded。在这里,frame也会有正确的值。

最小的例子:

class MyViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()

let v = UIView(frame: .zero)
view.addSubview(v)
v.backgroundColor = .blue
v.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
v.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
v.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 30),
v.widthAnchor.constraint(equalToConstant: 100),
v.heightAnchor.constraint(equalToConstant: 100)
])
let u = UIView(frame: .init(x: 10, y: 10, width: 100, height: 100))
view.addSubview(u)
u.backgroundColor = .red
u.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
u.topAnchor.constraint(equalTo: v.bottomAnchor, constant: 10),
u.leftAnchor.constraint(equalTo: v.leftAnchor),
u.widthAnchor.constraint(equalToConstant: 100),
u.heightAnchor.constraint(equalToConstant: 100)
])

// before any layout
print(u.frame)
// laying out u, doesn't change anything
u.layoutIfNeeded()
// note that the above could change the frame of u depending on the frame 
// of u and its size constraints, but I've deliberately chosen these
// values and constraints so that it matches your behaviour
print(u.frame)
// laying out u, and v, making u.frame what you expect
view.layoutIfNeeded() // view is the common parent between u and v
print(u.frame)
}
}

相关内容

  • 没有找到相关文章

最新更新