有的東西雖然基礎,但是耐不住人老記性差呀,自己寫下來好過次次再搜咯,so......
AnchorPoint 和 Position
AnchorPoint
anchorPoint
直譯過來就是錨點,layer 以該點為基準進行各種 transform 變換,其值從 (0, 0) 到 (1, 1),預設值為 (0.5, 0.5)。該屬性的文件中提到:
'(0, 0)' is the bottom left corner of the bounds rect, '(1, 1)' is the top right corner
這裡的說的左下角,是在以螢幕的左上角為原點的座標系中。而在我們日常生活的座標系中,原點在螢幕的左下角,那麼 (0, 0) 位置則是左上角。
Position
實際表示的是錨點在superLayer
中的位置。
兩者的聯絡
單獨修anchorPoint
或position
可以修改掉 layer 的位置,但是並不會對另一個屬性造成影響。下面例子中,藍色檢視的frame.size = (100.0, 100.0)
,有一個frame.size = (0, 0, 100.0, 100.0)
的黃色子檢視。
單獨修改anchorPoint
:
單獨修改position
:
從以上的輸出可以看出,單獨修改這兩個屬性,發生改變的其實是黃色檢視的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
的值。
CALayer 和 UIView 的位置、大小
其實 view 的frame
、bounds
、center
都是直接返回了 layer 的frame
、bounds
、position
屬性。
Frame 和 Bounds
不管frame
還是bounds
,都需要一個參考座標系。frame
參考的是父檢視的座標系,表示在父檢視座標系中的位置和大小;bounds
參考的是自身檢視的座標系,表示在自身檢視座標系中的位置和大小。
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 的 contentOffset
初識 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 滾動時輸出兩個屬性證明了以上的幾個說法。