代码之家  ›  专栏  ›  技术社区  ›  toraritte

当UIView的“bounds”原点以正数递增时,为什么子视图会向负方向移动?

  •  1
  • toraritte  · 技术社区  · 7 年前

    这一定很简单,我的基本数学知识可能不够。这是清楚的(从 this question

    视图的框架决定其 superview中的位置 . 视图边界 子视图位置 . 也就是说,如果你改变视角 位置将更改。

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let v1 = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 300))
            v1.backgroundColor = UIColor.blue
    
            let v2 = UIView(frame: v1.bounds.insetBy(dx: 50, dy: 50))
            v2.backgroundColor = UIColor.red
    
            self.view.addSubview(v1)
            v1.addSubview(v2)
        }
    

    在LLDB控制台上检查,这也非常清楚:

    (lldb) p v1.frame
    (CGRect) $R0 = (origin = (x = 100, y = 100), size = (width = 200, height = 300))
    (lldb) p v1.bounds
    (CGRect) $R1 = (origin = (x = 0, y = 0), size = (width = 200, height = 300))
    
    (lldb) p v2.frame
    (CGRect) $R2 = (origin = (x = 50, y = 50), size = (width = 100, height = 200))
    (lldb) p v2.bounds
    (CGRect) $R3 = (origin = (x = 0, y = 0), size = (width = 100, height = 200))
    

    A red square positioned in the middle of a blue square

    添加 v1.bounds.origin.x += 50 v1.bounds.origin.x = 50 关于那件事)之后 v1.addSubview(v2)

    (lldb) p v1.frame
    (CGRect) $R0 = (origin = (x = 100, y = 100), size = (width = 200, height = 300))
    (lldb) p v1.bounds
    (CGRect) $R1 = (origin = (x = 50, y = 0), size = (width = 200, height = 300))
    
    (lldb) p v2.frame
    (CGRect) $R2 = (origin = (x = 50, y = 50), size = (width = 100, height = 200))
    (lldb) p v2.bounds
    (CGRect) $R3 = (origin = (x = 0, y = 0), size = (width = 100, height = 200))
    

    LLDB控制台输出仍然符合我目前的理解,但它是如何呈现的:

    Red square lined up with the left wall of the blue square

    我试着解释一下(见下文),我知道视图的坐标系是相对的,但是如果加上50 v1 origin.x ,子视图的有效 frame.origin 应该是的 (x=50+50, y=0)

    2 回复  |  直到 7 年前
        1
  •  1
  •   toraritte    7 年前

    我在马特·纽伯格的书中找到了一个令人满意的答案 Programming iOS 11 book 举一个类似的例子:

    /* ... */
    let v2 = UIView(frame:v1.bounds.insetBy(dx: 10, dy: 10))
    /* ... */
    v1.bounds.origin.x += 10
    v1.bounds.origin.y += 10
    

    已向上和向左移动,因此它与其超级视图齐平 左上角。基本上,我们所做的就是对 超级视图, 而不是在你的左上角打电话 (0.0,0.0),调用该点(10.0,10.0)。 原点本身位于(10.0,10.0),子视图现在与 超级视图左上角。更改视图的效果 原点可能看起来方向向后,我们增加了超视距 原点在正方向,但子视图在正方向移动 相反的方向,但是这样想:一个原点 点与左上角的框架重合。

    因此,它似乎修改了 origin 更像是一个映射操作,而不是坐标系转换。这也解释了为什么这些结果是相同的 += 50 = 50

    enter image description here

        2
  •  0
  •   Joshua Kaden    7 年前

    通过调整 边界' 在v1的origin.x中,您正在将origin扩展到可见矩形之外(这就是UIScrollView的工作原理。)

    如果改为修改