iOS核心動畫筆記4-圖形幾何學

圖層幾何學

1. 佈局

UIView有三個比較重要的屬性: frame, bounds, center. CALayer對應的叫作: frame,bounds,position. frame表明圖層外部座標, bounds是內部座標.工具

視圖的frame, bounds, center屬性僅僅是存取方法, 當操做視圖的frame時候,其實是改變位於視圖下方CALayer的frame, 不能獨立於圖層以外改變視圖的frame. 對於視圖和圖層來講, frame並非一個很是清晰的屬性,他實際上是一個虛擬的屬性, 是根據bounds, position和transform計算而來的, 當其中任意一值發生變化, frame都會變化, 一樣的, frame也會影響到他們當中的值.佈局

當圖層作變換時候, 好比旋轉或者縮放, frame實際上表明的是覆蓋在圖層旋轉以後的整個軸對稱對齊的矩形區域, 就是說, frame和bounds寬高再也不保持一致.測試

2. 錨點

anchorPoint默認位於圖層的中點, 因此圖層將會以這個點爲中心放置. 圖層的anchorPoint是能夠被移動的, 好比當把它置於圖層frame的左上角, 因而圖層內容將會向右下角的Position方向移動.3d

anchorPoint也使用單位座標來描述. 當改變anchorPoint時候, Position屬性保持固定, 可是frame卻會發生變化.code

一個移動anchorPoint而不應表frame的方法:orm

簡單地說, 就是改變Position, 測試發現, 例如, 將anchorPoint移動到左上角, 正常狀況下, frame會向右下角移動0.5的單位, 若是改變anchorPoint的同時, 更改Position, Position的向左上角移動0.5*frame.size.width, 這時候, frame看起來就是不動的.對象

不過這點關係, 仍是有點迷糊.....blog

3. 座標系

CALayer給不一樣座標系之間的圖層轉換提供了一些工具類方法, 相似於視圖之間座標系的轉換方法:事件

- (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer; 
- (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer; 
- (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;
- (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;

4. z座標軸

UIView位於嚴格的二維座標系中, CALayer存在於三維空間中, 它的aPosition和anchorPointZ都是在z軸上面描述圖層位置的浮點類型. zPosition在大多數狀況下不經常使用, 它的主要功能就是改變圖層的顯示順序.get

最好使用圖層相關的視圖, 而不直接使用圖層, 主要緣由是由於要處理額外的複雜的觸摸事件. CALayer並不關心任何響應鏈事件, 因此不能直接處理觸摸事件或者手勢. 可是它也有幾個方法能夠幫你處理事件: -containsPoint:和-hitTest:

-containsPoint: 接受一個在本圖層座標系下的CGPoint, 若是點在bounds內, 返回YES. 缺點是, 若是使用這種方法, 須要將發生事件的位置, 轉換到每個layer座標系當中去, 不方便.

-hitTest: 一樣接受一個CGPoint類型參數, 返回值是圖層自己, 既發生點擊事件的圖層. 若是點不在此圖層樹範圍內, 則返回nil.

code:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    //獲取發生在view上的一個點
    CGPoint point = [[touches anyObject] locationInView:self.view];
    
    //經過hitTest方法找到點在哪一個layer上面. 返回值是CALayer對象, UIView也有相關的方法
    CALayer *targetLayer = [self.view.layer hitTest:point];
    
    if (targetLayer == self.greenLayer) {
        NSLog(@"綠色 layer");
    }
    if (targetLayer == self.redLayer) {
        NSLog(@"紅色 layer");
    }

}
相關文章
相關標籤/搜索