[iOS Animation]-CALayer 專用圖層 CATransformLayer

CATransformLayer

當咱們在構造複雜的3D事物的時候,若是可以組織獨立元素就太方便了。好比說,你想創造一個孩子的手臂:你就須要肯定哪一部分是孩子的手腕,哪一部分是孩子的前臂,哪一部分是孩子的肘,哪一部分是孩子的上臂,哪一部分是孩子的肩膀等等。 git

固然是容許獨立地移動每一個區域的啦。以肘爲指點會移動前臂和手,而不是肩膀。Core Animation圖層很容易就可讓你在2D環境下作出這樣的層級體系下的變換,可是3D狀況下就不太可能,由於全部的圖層都把他的孩子都平面化到一個場景中(第五章『變換』有提到)。 github

CATransformLayer解決了這個問題,CATransformLayer不一樣於普通的CALayer,由於它不能顯示它本身的內容。只有當存在了一個能做用域子圖層的變換它才真正存在。CATransformLayer並不平面化它的子圖層,因此它可以用於構造一個層級的3D結構,好比個人手臂示例。 數組

用代碼建立一個手臂須要至關多的代碼,因此我就演示得更簡單一些吧:在第五章的立方體示例,咱們將經過旋轉camara來解決圖層平面化問題而不是像立方體示例代碼中用的sublayerTransform。這是一個很是不錯的技巧,可是隻能做用域單個對象上,若是你的場景包含兩個立方體,那咱們就不能用這個技巧單獨旋轉他們了。 app

那麼,就讓咱們來試一試CATransformLayer吧,第一個問題就來了:在第五章,咱們是用多個視圖來構造了咱們的立方體,而不是單獨的圖層。咱們不能在不打亂已有的視圖層次的前提下在一個自己不是有寄宿圖的圖層中放置一個寄宿圖圖層。咱們能夠建立一個新的UIView子類寄宿在CATransformLayer(用+layerClass方法)之上。可是,爲了簡化案例,咱們僅僅重建了一個單獨的圖層,而不是使用視圖。這意味着咱們不能像第五章同樣在立方體表面顯示按鈕和標籤,不過咱們如今也用不到這個特性。 dom

清單6.5就是代碼。咱們以咱們在第五章使用過的相同基本邏輯放置立方體。可是並不像之前那樣直接將立方面添加到容器視圖的宿主圖層,咱們將他們放置到一個CATransformLayer中建立一個獨立的立方體對象,而後將兩個這樣的立方體放進容器中。咱們隨機地給立方面染色以將他們區分開來,這樣就不用靠標籤或是光亮來區分他們。圖6.5是運行結果。 atom

清單6.5 用CATransformLayer裝配一個3D圖層體系 spa

複製代碼
@interface ViewController () @property (nonatomic, weak) IBOutlet UIView *containerView; @end @implementation ViewController - (CALayer *)faceWithTransform:(CATransform3D)transform { //create cube face layer CALayer *face = [CALayer layer]; face.frame = CGRectMake(-50, -50, 100, 100); //apply a random color CGFloat red = (rand() / (double)INT_MAX); CGFloat green = (rand() / (double)INT_MAX); CGFloat blue = (rand() / (double)INT_MAX); face.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor; //apply the transform and return face.transform = transform; return face; } - (CALayer *)cubeWithTransform:(CATransform3D)transform { //create cube layer CATransformLayer *cube = [CATransformLayer layer]; //add cube face 1 CATransform3D ct = CATransform3DMakeTranslation(0, 0, 50); [cube addSublayer:[self faceWithTransform:ct]]; //add cube face 2 ct = CATransform3DMakeTranslation(50, 0, 0); ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0); [cube addSublayer:[self faceWithTransform:ct]]; //add cube face 3 ct = CATransform3DMakeTranslation(0, -50, 0); ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0); [cube addSublayer:[self faceWithTransform:ct]]; //add cube face 4 ct = CATransform3DMakeTranslation(0, 50, 0); ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0); [cube addSublayer:[self faceWithTransform:ct]]; //add cube face 5 ct = CATransform3DMakeTranslation(-50, 0, 0); ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0); [cube addSublayer:[self faceWithTransform:ct]]; //add cube face 6 ct = CATransform3DMakeTranslation(0, 0, -50); ct = CATransform3DRotate(ct, M_PI, 0, 1, 0); [cube addSublayer:[self faceWithTransform:ct]]; //center the cube layer within the container CGSize containerSize = self.containerView.bounds.size; cube.position = CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0); //apply the transform and return cube.transform = transform; return cube; } - (void)viewDidLoad { [super viewDidLoad]; //set up the perspective transform CATransform3D pt = CATransform3DIdentity; pt.m34 = -1.0 / 500.0; self.containerView.layer.sublayerTransform = pt; //set up the transform for cube 1 and add it CATransform3D c1t = CATransform3DIdentity; c1t = CATransform3DTranslate(c1t, -100, 0, 0); CALayer *cube1 = [self cubeWithTransform:c1t]; [self.containerView.layer addSublayer:cube1]; //set up the transform for cube 2 and add it CATransform3D c2t = CATransform3DIdentity; c2t = CATransform3DTranslate(c2t, 100, 0, 0); c2t = CATransform3DRotate(c2t, -M_PI_4, 1, 0, 0); c2t = CATransform3DRotate(c2t, -M_PI_4, 0, 1, 0); CALayer *cube2 = [self cubeWithTransform:c2t]; [self.containerView.layer addSublayer:cube2]; } @end
複製代碼

 

圖6.5

圖6.5 同一視角下的倆不一樣變換的立方體 code

CAGradientLayer

CAGradientLayer是用來生成兩種或更多顏色平滑漸變的。用Core Graphics複製一個CAGradientLayer並將內容繪製到一個普通圖層的寄宿圖也是有可能的,可是CAGradientLayer的真正好處在於繪製使用了硬件加速。 orm

基礎漸變

咱們將從一個簡單的紅變藍的對角線漸變開始(見清單6.6).這些漸變色彩放在一個數組中,並賦給colors屬性。這個數組成員接受CGColorRef類型的值(並非從NSObject派生而來),因此咱們要用經過bridge轉換以確保編譯正常。 對象

CAGradientLayer也有startPoint和endPoint屬性,他們決定了漸變的方向。這兩個參數是以單位座標系進行的定義,因此左上角座標是{0, 0},右下角座標是{1, 1}。代碼運行結果如圖6.6

清單6.6 簡單的兩種顏色的對角線漸變

複製代碼
@interface ViewController () @property (nonatomic, weak) IBOutlet UIView *containerView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //create gradient layer and add it to our container view CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.frame = self.containerView.bounds; [self.containerView.layer addSublayer:gradientLayer]; //set gradient colors gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor]; //set gradient start and end points gradientLayer.startPoint = CGPointMake(0, 0); gradientLayer.endPoint = CGPointMake(1, 1); } @end
複製代碼

 

圖6.6

圖6.6 用CAGradientLayer實現簡單的兩種顏色的對角線漸變

相關文章
相關標籤/搜索