本文 demo 地址git
有的東西雖然基礎,可是耐不住人老記性差呀,本身寫下來好過次次再搜咯,so......github
anchorPoint
直譯過來就是錨點,layer 以該點爲基準進行各類 transform 變換,其值從 (0, 0) 到 (1, 1),默認值爲 (0.5, 0.5)。該屬性的文檔中提到:swift
'(0, 0)' is the bottom left corner of the bounds rect, '(1, 1)' is the top right cornerspa
這裏的說的左下角,是在以屏幕的左上角爲原點的座標系中。而在咱們平常生活的座標系中,原點在屏幕的左下角,那麼 (0, 0) 位置則是左上角。3d
實際表示的是錨點在superLayer
中的位置。code
單獨修anchorPoint
或position
能夠修改掉 layer 的位置,可是並不會對另外一個屬性形成影響。下面例子中,藍色視圖的frame.size = (100.0, 100.0)
,有一個frame.size = (0, 0, 100.0, 100.0)
的黃色子視圖。orm
單獨修改anchorPoint
:cdn
單獨修改position
:blog
從以上的輸出能夠看出,單獨修改這兩個屬性,發生改變的實際上是黃色視圖的frame.origin
。不可貴到規律:文檔
frame.origin.x = position.x - anchorPoint.x * bounds.size.width
frame.origin.y = position.y - anchorPoint.y * bounds.size.height
複製代碼
若是想要修改錨點後,origin
位置不發生變化,根據以上公式,則須要相應的修改position
,或者直接暴力的修改origin
的值。
其實 view 的frame
、bounds
、center
都是直接返回了 layer 的frame
、bounds
、position
屬性。
無論frame
仍是bounds
,都須要一個參考座標系。frame
參考的是父視圖的座標系,表示在父視圖座標系中的位置和大小;bounds
參考的是自身視圖的座標系,表示在自身視圖座標系中的位置和大小。
藍色視圖 A 的frame.size = (100.0, 100.0)
,有一個frame.size = (0, 0, 100.0, 100.0)
的黃色子視圖 B。在修改 Abounds = (-20, -20, 100.0, 100.0)
的時候,如圖:
A 的位置不變,B 的位置往右下偏移。由於 A 的origin
在其自身座標系中的位置變爲了 (-20, -20),B 的frame.origin
仍是 (0, 0),表示 B 在 A 的座標系中位置爲 (0, 0),那麼 B 的左上角就相對於 A 的左上角向右下各偏移了 20。
初識 UIScrollView 的時候,我覺得在拖動它時,是經過修改子視圖的frame
來產生位移效果的。其實思考一下就會獲得子視圖位移距離的規律:
translocation.x = subView.frame.origin.x - superview.bounds.origin.x
translocation.y = subView.frame.origin.y - superview.bounds.origin.y
複製代碼
恰好 scrollView 的原理實際上是修改了自身的bounds
,而不是修改子視圖的frame
。
不巧的是,contentOffset
和bounds
的值又是如出一轍的,咱們能夠理解爲它只是bounds
屬性的一個殼。本文的 demo 中就用了一個 tableView 滾動時輸出兩個屬性證實了以上的幾個說法。