英文:
Unexpected behaviour of UIView.convert(_ point:to:)
问题
我正在尝试将一些视图中心转换为能够在这些 CGPoint
之间绘制一条线。
然而,由于这些点在垂直方向上完全对齐,convert
方法返回了意外的值。显然,我漏掉了一些东西,无法弄清楚。这里我正在询问:)
我迅速设置了这个代码,以重新创建这个问题:
class ViewController: UIViewController {
// ...(省略了一些代码)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let firstCenter1 = firstSubview.convert(firstSubview.center, to: view)
let secondCenter1 = secondSubview.convert(secondSubview.center, to: view)
print(firstCenter1, secondCenter1)
}
}
打印结果为 (45.0, 84.0) (55.0, 134.0)
,然而,正如我所期望的,我应该打印出 (45.0, 84.0) (45.0, 134.0)
。因为secondSubview
的相对 center.x
实际上是 45.0
,就像 firstSubview
一样。
我混合和匹配了 convert
的参数和接收者,但没有运气。即使我获得了 center.x
,然后 center.y
也会给出错误的值。
我在这里漏掉了什么?
英文:
I am trying to convert some view centers' to be able to draw a line between those CGPoint
s.
However those points are perfectly aligned vertically, convert
method returns unexpected values. Clearly I do miss something and could not figure out. Here I am asking
I quickly setup this code recreating the issue:
class ViewController: UIViewController {
private lazy var backgroundView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemBackground
return view
}()
private lazy var firstView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemRed
return view
}()
private lazy var secondView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemBlue
return view
}()
private lazy var firstSubview: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemMint
return view
}()
private lazy var secondSubview: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemGreen
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(backgroundView)
backgroundView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
backgroundView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
backgroundView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
backgroundView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
backgroundView.addSubview(firstView)
backgroundView.addSubview(secondView)
firstView.topAnchor.constraint(equalTo: backgroundView.topAnchor).isActive = true
firstView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
firstView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
secondView.topAnchor.constraint(equalTo: firstView.bottomAnchor, constant: 10).isActive = true
secondView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
secondView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
firstView.addSubview(firstSubview)
firstSubview.topAnchor.constraint(equalTo: firstView.topAnchor).isActive = true
firstSubview.bottomAnchor.constraint(equalTo: firstView.bottomAnchor).isActive = true
firstSubview.leadingAnchor.constraint(equalTo: firstView.leadingAnchor).isActive = true
firstSubview.heightAnchor.constraint(equalToConstant: 50).isActive = true
firstSubview.widthAnchor.constraint(equalToConstant: 50).isActive = true
secondView.addSubview(secondSubview)
secondSubview.topAnchor.constraint(equalTo: secondView.topAnchor).isActive = true
secondSubview.bottomAnchor.constraint(equalTo: secondView.bottomAnchor).isActive = true
secondSubview.leadingAnchor.constraint(equalTo: secondView.leadingAnchor, constant: 10).isActive = true
secondSubview.heightAnchor.constraint(equalToConstant: 30).isActive = true
secondSubview.widthAnchor.constraint(equalToConstant: 30).isActive = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let firstCenter1 = firstSubview.convert(firstSubview.center, to: view)
let secondCenter1 = secondSubview.convert(secondSubview.center, to: view)
print(firstCenter1, secondCenter1)
}
}
The print results as (45.0, 84.0) (55.0, 134.0)
, however, as I would expect, I should print out (45.0, 84.0) (45.0, 134.0)
. Because the relative center.x
of the secondSubview
is literally 45.0
just as firstSubview
.
I mixed and matched convert
's parameters and receiver but no luck. Even if I got center.x
, then center.y
gives the wrong value.
What am I missing here?
答案1
得分: 1
center
属性返回父视图坐标系统中的一个点。
中心点在其父视图的坐标系统中以点为单位指定。设置此属性会相应地更新
frame
属性中的矩形的原点。
因此,您不应该在子视图上调用convert
。您应该在firstView
和secondView
上调用它:
let firstCenter1 = firstView.convert(firstSubview.center, to: view)
let secondCenter1 = secondView.convert(secondSubview.center, to: view)
英文:
The center
property returns a point in the parent's coordinate system.
> The center point is specified in points in the coordinate system of its superview. Setting this property updates the origin of the rectangle in the frame
property appropriately.
Therefore, you should not call convert
on the subviews. You should call it on firstView
and secondView
:
let firstCenter1 = firstView.convert(firstSubview.center, to: view)
let secondCenter1 = secondView.convert(secondSubview.center, to: view)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论