CALayer透視投影修改
動畫案例準(zhǔn)備工作:新建空工程CoreAnimation-Transform
陆爽,在Main.storyboard
文件中拖入一個UIImageView
,添加圖片資源進行配置并關(guān)連,命名為layerView
案例一:下面實現(xiàn)一張圖片
圍繞一個Y軸
旋轉(zhuǎn)
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *layerView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// CATransform3D矩陣可以是一個旋轉(zhuǎn)矩陣仆百、平移矩陣、縮放矩陣奔脐、投影矩陣
// 參數(shù)一:圍繞角度
// 參數(shù)二:圍繞x軸
// 參數(shù)三:圍繞y軸
// 參數(shù)四:圍繞z軸
CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
self.layerView.layer.transform = transform;
}
@end
運行工程俄周,我們查看圖片發(fā)現(xiàn)并沒有旋轉(zhuǎn)效果
吁讨,圖片甚至發(fā)生了變形。
案例二:修改代碼圍繞Z軸旋轉(zhuǎn)并查看效果
CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
通過對比發(fā)現(xiàn)峦朗,圍繞Z軸
可以發(fā)生旋轉(zhuǎn)建丧,而圍繞Y軸
我們并沒有查看出旋轉(zhuǎn)效果氧敢。是什么原因造成圖片沒有辦法圍繞Y軸旋轉(zhuǎn)呢
罩锐?
原因是在投影的時候西乖,圖片是平面的漱逸;對Y軸
進行投影礁芦,我們沒有考慮投影方式炒事,如果我們要想呈現(xiàn)立體效果方咆,我們就要設(shè)置透視投影
的方式浸船。
案例三:設(shè)置透視投影方式
- (void)viewDidLoad {
[super viewDidLoad];
//投影方式: 2種.正投影,透視投影;
//CATransform3DIdentity表示單元矩陣
CATransform3D transform1 = CATransform3DIdentity;
//m34表示透視投影迄埃,500表示投影的距離疗韵,一般為500/1000
transform1.m34 = -1.0/500.0;
/*
CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle,
CGFloat x, CGFloat y, CGFloat z)
參數(shù)1: t,矩陣CATransform3D對象
參數(shù)2: 角度(弧度為單位,如果是度數(shù)需要做轉(zhuǎn)化)
參數(shù)3: x, (1=旋轉(zhuǎn),0=不旋轉(zhuǎn))
參數(shù)4: y,
參數(shù)5: z,
*/
transform1 = CATransform3DRotate(transform1, M_PI_4, 0, 1, 0);
self.layerView.layer.transform = transform1;
}
我們在做3D旋轉(zhuǎn)
的時候,如果針對的是一個平面圖形侄非,我們要想呈現(xiàn)立體效果
蕉汪,就要設(shè)置透視投影
的屬性。
注意:設(shè)置投影方式跟圍繞哪個軸旋轉(zhuǎn)并沒有關(guān)系
逞怨,只是讓圖形呈現(xiàn)出立體效果
者疤;如果對圖形平移并且想要呈現(xiàn)立體效果,也需要設(shè)置投影方式叠赦。
滅點
:在透視投影中驹马,一束平行于投影面的平行線的投影可以保持平行,而不平行于投影面的平行線的投影會聚集到一個點除秀,這個點稱為滅點糯累;滅點可以看作是無限遠處的一點在投影面上的投影
。
案例四:兩張圖片都呈現(xiàn)透視投影
的方式(同時可以引申為多張圖片)
Main.storyboard
文件中拖入一個UIView
并命名為containerView
册踩,在containerView
上分別拖入兩個UIImageView
并命名為layerView1
泳姐、layerView2
代碼如下
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (weak, nonatomic) IBOutlet UIImageView *layerView1;
@property (weak, nonatomic) IBOutlet UIImageView *layerView2;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/500;
//sublayerTransform 子圖層上仿射變換(會影響添加在此圖層上的子圖層)
self.containerView.layer.sublayerTransform = perspective;
CATransform3D transform2 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
CATransform3D transform3 = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);
self.layerView1.layer.transform = transform2;
self.layerView2.layer.transform = transform3;
}
@end
運行工程,兩張圖片都發(fā)生了旋轉(zhuǎn)
暂吉,效果圖如下
案例五:圖片旋轉(zhuǎn)180度
胖秒,查看圖片背面效果
- (void)viewDidLoad {
[super viewDidLoad];
CATransform3D transform1 = CATransform3DIdentity;
transform1.m34 = -1.0/500.0;
transform1 = CATransform3DRotate(transform1, M_PI, 0, 1, 0);
self.layerView.layer.transform = transform1;
}
運行工程,我們發(fā)現(xiàn)可以看到圖片背面的效果
慕的,原因是圖層默認(rèn)開啟正背面渲染
扒怖。
舉例:如果想要呈現(xiàn)一個正方體
的立體效果,默認(rèn)情況下最多可以看到三個面业稼,剩下看不到的三個面是不需要畫出來的盗痒,OpenGL ES
不會去畫看不到的三個面,這樣的話性能就會提高50%
。所以這里我們可以根據(jù)業(yè)務(wù)場景關(guān)閉圖層的正背面渲染屬性
俯邓,以提高渲染性能骡楼。
案例六:關(guān)閉圖層的正背面渲染
- (void)viewDidLoad {
[super viewDidLoad];
CATransform3D transform1 = CATransform3DIdentity;
transform1.m34 = -1.0/500.0;
transform1 = CATransform3DRotate(transform1, M_PI, 0, 1, 0);
self.layerView.layer.transform = transform1;
//正背面渲染--> 渲染技術(shù)正背面剔除,判斷用戶可見/不可見
self.layerView.layer.doubleSided = NO;
}
再次運行工程,我們就看不到圖片的背面效果稽鞭。
透視投影實現(xiàn)立體盒子
動畫案例準(zhǔn)備工作:新建空工程CoreAnimation5
鸟整,在Main.storyboard
文件中拖入兩個UIView
,其中一個view
是另一個view
的子視圖朦蕴;父視圖view
命名為outerView
篮条,背景色設(shè)置為紅色,子視圖view
命名為innerView
吩抓,背景色設(shè)置為藍色涉茧。
案例七:父視圖圍繞Z軸
順時針旋轉(zhuǎn)45度
,子視圖圍繞Z軸
逆時針旋轉(zhuǎn)45度
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *outerView;
@property (weak, nonatomic) IBOutlet UIView *innerView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CATransform3D outer = CATransform3DIdentity;
//透視投影
outer.m34 = -1.0/500;
//旋轉(zhuǎn)變換,圍繞Z軸.45度
outer = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
self.outerView.layer.transform = outer;
CATransform3D inner = CATransform3DIdentity;
inner.m34 = -1.0/500;
inner = CATransform3DMakeRotation(-M_PI_4, 0, 0, 1);
self.innerView.layer.transform = inner;
}
@end
疑問:為什么沒有達到我們預(yù)期的效果呢疹娶?
因為手機屏幕是平面的伴栓,紅色view
往內(nèi)旋轉(zhuǎn),藍色view
往外旋轉(zhuǎn)雨饺,旋轉(zhuǎn)的軸就會相悖钳垮,這時候就需要一個立體空間
來解決;如果要想實現(xiàn)預(yù)期效果额港,就要使用3D圖層
饺窿;即CALayer
無法實現(xiàn),需要專門的3D圖層CATransformLayer
來實現(xiàn)移斩。
案例八:使用CATransformLayer
圖層實現(xiàn)立體效果
新建帶xib
文件的CCViewController
頁面肚医,并在CCViewController
頁面的View
上拖入一個UIView
命名為containerView
,背景色設(shè)置為黑色
叹哭,然后再分別拖入6個UIView
忍宋,分別命名為view0
痕貌、view1
风罩、view2
、view3
舵稠、view4
超升、view5
如下圖所示
#import "CCViewController.h"
@interface CCViewController ()
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) IBOutlet UIView *view0;
@property (strong, nonatomic) IBOutlet UIView *view1;
@property (strong, nonatomic) IBOutlet UIView *view2;
@property (strong, nonatomic) IBOutlet UIView *view3;
@property (strong, nonatomic) IBOutlet UIView *view4;
@property (strong, nonatomic) IBOutlet UIView *view5;
@property(nonatomic,strong)NSArray *faces;
@end
@implementation CCViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.faces = @[_view0,_view1,_view2,_view3,_view4,_view5];
//我們不用修改子視圖,只修改父視圖
//父View的layer圖層
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0 / 500.0;
//父視圖旋轉(zhuǎn)之后查看立體效果哺徊,沿X軸室琢、Y軸分別旋轉(zhuǎn)一次就能看到正方體的三個面
perspective = CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);
perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);
self.containerView.layer.sublayerTransform = perspective;
//add cube face 1
//Z軸平移100
CATransform3D transform = CATransform3DMakeTranslation(0, 0, 100);
[self addFace:0 withTransform:transform];
//add cube face 2
transform = CATransform3DMakeTranslation(100, 0, 0);
transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
[self addFace:1 withTransform:transform];
//add cube face 3
transform = CATransform3DMakeTranslation(0, -100, 0);
transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
[self addFace:2 withTransform:transform];
//add cube face 4
transform = CATransform3DMakeTranslation(0, 100, 0);
transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
[self addFace:3 withTransform:transform];
//add cube face 5
transform = CATransform3DMakeTranslation(-100, 0, 0);
transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
[self addFace:4 withTransform:transform];
//add cube face 6
transform = CATransform3DMakeTranslation(0, 0, -100);
transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
[self addFace:5 withTransform:transform];
}
- (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform
{
//獲取face視圖并將其添加到容器中
UIView *face = self.faces[index];
[self.containerView addSubview:face];
//將face視圖放在容器的中心
CGSize containerSize = self.containerView.bounds.size;
face.center = CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);
//添加transform
face.layer.transform = transform;
}
@end
ViewController
頁面添加跳入CCViewController
頁面的邏輯,運行工程查看立體效果
父視圖containerView
本身的transform
并沒有發(fā)生變化落追,只是一個平面盈滴,只是其子視圖發(fā)生了透視投影
,讓其子視圖發(fā)生位置與角度的變化。
CAShaperLayer
CoreAnimation
專用圖層
CAShaperLayer
CAShaperLayer
是?個通過?量圖形指定諸如顏?和線寬等屬性巢钓,?CGPath
來定義想要繪制的圖形病苗,最后CAShaperLayer
就能渲染出現(xiàn)
-
渲染快速
。CAShapeLayer
使?了硬件加速器症汹,繪制同?圖形會?用Core Graphics
快很多硫朦。 -
?效使用內(nèi)存
。?個CAShapeLayer
不需要像普通CALayer
一樣創(chuàng)建?個寄宿圖形背镇,所以?論有多大咬展,都不會占?用太多的內(nèi)存。 -
不會被圖層邊界剪裁掉
瞒斩。?個CAShapeLayer
可以在邊界之外繪制破婆。你的圖層路徑不會像在使用Core Graphics
的普通CALayer
一樣被剪裁掉。 -
不會出現(xiàn)像素化
济瓢。當(dāng)你給CAShapeLayer
做3D變換時荠割,它不像?個有寄宿圖的普通圖層一樣變得像素化。
案例九:使用CAShaperLayer
繪制火柴人
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(175, 100)];
//繪制一個圓形
[path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
[path moveToPoint:CGPointMake(150, 125)];
[path addLineToPoint:CGPointMake(150, 175)];
[path addLineToPoint:CGPointMake(125, 225)];
[path moveToPoint:CGPointMake(150, 175)];
[path addLineToPoint:CGPointMake(175, 225)];
[path moveToPoint:CGPointMake(100, 150)];
[path addLineToPoint:CGPointMake(200, 150)];
//create shape layer
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
//stroke color 畫筆顏色
shapeLayer.strokeColor = [UIColor redColor].CGColor;
//fill color 填充顏色
shapeLayer.fillColor = [UIColor blueColor].CGColor;
//line width 線段寬度
shapeLayer.lineWidth = 5;
//形狀路徑連線樣式
shapeLayer.lineJoin = kCALineJoinRound;
//形狀路徑線帽樣式
shapeLayer.lineCap = kCALineCapRound;
//shaperLayer 繪制圖形路徑
shapeLayer.path = path.CGPath;
//add it to our view
[self.view.layer addSublayer:shapeLayer];
}
@end
使用CAShaperLayer
繪制圓角旺矾,也可以實現(xiàn)部分圓角
- (void)viewDidLoad {
[super viewDidLoad];
//define path parameters
CGRect rect = CGRectMake(50, 50, 100, 100);
CGSize radii = CGSizeMake(20, 20);
UIRectCorner corners1 = UIRectCornerBottomRight | UIRectCornerBottomLeft;
UIRectCorner corners2 = UIRectCornerTopLeft | UIRectCornerTopRight;
//create path
UIBezierPath *path2 = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners2 cornerRadii:radii];
//create shape layer
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
//stroke color 畫筆顏色
shapeLayer.strokeColor = [UIColor redColor].CGColor;
//fill color 填充顏色
shapeLayer.fillColor = [UIColor blueColor].CGColor;
//line width 線段寬度
shapeLayer.lineWidth = 5;
//形狀路徑連線樣式
shapeLayer.lineJoin = kCALineJoinRound;
//形狀路徑線帽樣式
shapeLayer.lineCap = kCALineCapRound;
//shaperLayer 繪制圖形路徑
shapeLayer.path = path2.CGPath;
//add it to our view
[self.view.layer addSublayer:shapeLayer];
}
CATextLayer圖層講解
如果你想在一個圖層?面顯示?字蔑鹦,完全可以借助圖層代替字符串,可以使?CATextLayer
將內(nèi)容寫入圖層箕宙;UILabel
的原理是通過Core Graphics
寫入內(nèi)容嚎朽,CATextLayer
幾乎包含了所有UILabel
的繪制特性,而且比UILabel
渲染要快很多柬帕。
案例:使用CATextLayer
來渲染文字
- (void)viewDidLoad {
[super viewDidLoad];
//create a text layer
CATextLayer *textLayer = [CATextLayer layer];
textLayer.frame = CGRectMake(10,100 , self.view.frame.size.width -20, 200);
[self.view.layer addSublayer:textLayer];
//set text attributes(設(shè)置text的屬性)
//字體顏色
textLayer.foregroundColor = [UIColor blackColor].CGColor;
//對齊方式
textLayer.alignmentMode = kCAAlignmentCenter;
//環(huán)繞在邊界范圍內(nèi)
textLayer.wrapped = YES;
//choose a font (選擇字體)
UIFont *font = [UIFont systemFontOfSize:15];
//set layer font (設(shè)置圖層字體)
//將font改成圖層字體
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
textLayer.font = fontRef;
textLayer.fontSize = font.pointSize;
//模糊的原因是哟忍,沒有以Retina來渲染,contentsScale默認(rèn)值為1陷寝,所以需要傳合適的值
textLayer.contentsScale = [UIScreen mainScreen].scale;
//fontRef使用完要記著釋放
CGFontRelease(fontRef);
//choose some text 文字信息
NSString *text = @"Hello World";
//set layer text 設(shè)置layer的文字信息
textLayer.string = text;
}
CATextLayer
其實比UILabel
更加好用锅很,而且能夠支持富文本
。
案例:下面我們使用CATextLayer
來自定義UILabel
<!-- LayerLabel.h文件 -->
#import <UIKit/UIKit.h>
@interface LayerLabel : UILabel
@end
<!-- LayerLabel.m文件 -->
#import "LayerLabel.h"
@implementation LayerLabel
+ (Class)layerClass
{
return [CATextLayer class];
}
- (CATextLayer *)textLayer
{
return (CATextLayer *)self.layer;
}
- (void)setUp
{
//set defaults from UILabel settings
self.text = self.text;
self.textColor = self.textColor;
self.font = self.font;
[self textLayer].alignmentMode = kCAAlignmentJustified;
[self textLayer].wrapped = YES;
[self.layer display];
}
- (id)initWithFrame:(CGRect)frame
{
//called when creating label programmatically
if (self = [super initWithFrame:frame]) {
[self setUp];
}
return self;
}
- (void)awakeFromNib
{
//called when creating label using Interface Builder
[self setUp];
}
- (void)setText:(NSString *)text
{
super.text = text;
//set layer text
[self textLayer].string = text;
}
- (void)setTextColor:(UIColor *)textColor
{
super.textColor = textColor;
//set layer text color
[self textLayer].foregroundColor = textColor.CGColor;
}
- (void)setFont:(UIFont *)font
{
super.font = font;
//set layer font
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
[self textLayer].font = fontRef;
[self textLayer].fontSize = font.pointSize;
CGFontRelease(fontRef);
}
@end
Main.storyboard
拖入LayerLabel
控件凤跑,在ViewController.m
文件的viewDidLoad
方法中設(shè)置layerLabel
的text
值爆安。
@interface ViewController ()
@property (weak, nonatomic) IBOutlet LayerLabel *LLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.LLabel.text = @"Hello I'm LayerLabel";
}
@end
LayerLabel
的原理是替換UILabel
的圖層,其性能比原來的UILabel
更好仔引,渲染更快扔仓。
CATransformLayer圖層講解
CATransformLayer
是專?用來創(chuàng)建三維視圖的,上面我們使用的layer.sublayerTransform
實現(xiàn)的立體效果咖耘,下面我們使用CATransformLayer
來實現(xiàn)翘簇;OpenGL ES
也可以實現(xiàn),只是會很麻煩儿倒。
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *containerView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
//set up the perspective transform(設(shè)置投影矩陣)
//CATransformLayer的使用也是需要設(shè)置透視投影的
//如果想要有一個立體的投影效果版保,必須要設(shè)置投影方式,否則沒有立體效果
CATransform3D pt = CATransform3DIdentity;
pt.m34 = -1.0 / 500.0;
//設(shè)置子圖層是有透視效果的
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];
}
- (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;
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;
}
@end
CAGradientLayer圖層講解
CAGradientLayer
是?來?成兩種或更多種顏?平滑漸變,下面使用CAGradientLayer
來實現(xiàn)一個漸變色效果:
- (void)viewDidLoad {
[super viewDidLoad];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(10, 50, self.view.frame.size.width - 20, 100);
// locations數(shù)量要與colors一致彻犁,設(shè)置顏色位置
gradientLayer.locations = @[@0.25,@0.5,@0.25];
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor blueColor].CGColor,(__bridge id)[UIColor purpleColor].CGColor];
//startPoint蹈垢,endPoint 決定漸變方向,默認(rèn)左上角(0, 0) 右下角坐標(biāo)(1, 1)
//左上角的位置
gradientLayer.startPoint = CGPointMake(0, 0);
//右下角的位置
gradientLayer.endPoint = CGPointMake(1, 1);
[self.view.layer addSublayer:gradientLayer];
}
課后練習(xí):嘗試實現(xiàn)一個環(huán)形的漸變效果袖裕?
CARelicatorLayer圖層講解
CAReplicatorLayer
的目的就是為了高效?成許多相似的圖層曹抬,他會繪制一個或者多個圖層的子圖層,并在每個復(fù)制體上應(yīng)?不同的變換急鳄。
下面我們使用CAReplicatorLayer
來生成一個圖層的倒影
<!-- ReflectionView.h文件 -->
#import <UIKit/UIKit.h>
@interface ReflectionView : UIView
@end
<!-- ReflectionView.m文件 -->
#import "ReflectionView.h"
@implementation ReflectionView
+ (Class)layerClass
{
return [CAReplicatorLayer class];
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setUp];
}
return self;
}
- (void)awakeFromNib
{
[self setUp];
}
-(void)setUp
{
CAReplicatorLayer *layer = (CAReplicatorLayer *)self.layer;
// 復(fù)制數(shù)量為2
layer.instanceCount = 2;
CATransform3D transform = CATransform3DIdentity;
//間隔谤民,創(chuàng)建的兩個圖層之間的間隔
CGFloat veticalOffset = self.bounds.size.height + 2;
//平移的距離為veticalOffset
transform = CATransform3DTranslate(transform, 0, veticalOffset, 0);
//翻轉(zhuǎn)
transform = CATransform3DScale(transform, -1, -1, 0);
layer.instanceTransform = transform;
//K-0.7= 0.3,讓layer圖層的透明度為0.3
// 這里如果設(shè)置值為0.3疾宏,透明度就相當(dāng)于是 1 + 0.3 = 1.3
layer.instanceAlphaOffset = -0.7;
}
@end
Main.storyboard
文件中拖入一個ReflectionView
圖層张足,并在ReflectionView
上面添加一個UIImageView
且設(shè)置好圖片,運行工程查看效果如下