-
CALayer
*为什么要将UIView与CALayer 分开
避免重复代买mac os 和iOS交互手段不一样,所以要分开
![](https://img.haomeiwen.com/i3484821/a3db8a909c1dd745.png)
Layer-Tree Presentation-Tree 呈现树
Reader-Tree(Private) 渲染树
-
CABasicAnimation
移动的不是视图本身(隐藏),而是移动的是Presentation图层,在移动结束的时候消失
//动画结束后,layer会一直保持动画最后的状态
CA_EXTERN CAMediaTimingFillMode const kCAFillModeForwards
//在动画开始前,只要将动画加入一个layer,layer便立即进入动画的初始状态并等到动画开始
CA_EXTERN CAMediaTimingFillMode const kCAFillModeBackwards
//kCAFillModeForwards 和kCAFillModeBackwards组合
CA_EXTERN CAMediaTimingFillMode const kCAFillModeBoth
//默认,
CA_EXTERN CAMediaTimingFillMode const kCAFillModeRemoved
- CATransaction (隐视动画)
默认动画时长为:0.25s,通过runloop执行
*CALayer 常用属性 - contents
UIImage *image = [UIImage imageNamed:@"test.png"];
self.view.layer.contents = (__bridge id)image.CGImage;
self.view.layer.contentsGravity = kCAGravityResizeAspectFill;
self.view.contentMode = UIViewContentModeScaleAspectFill;
//CALayer 常用属性 - contentsScale
self.view.layer.contentsScale = [[UIScreen mainScreen]scale];
*CALayer 常用属性 - contentsRect
*CALayer 常用属性 - ZPosition (深度缓存区)
*CALayer 常用属性 - Hit Testing
hit test调用顺序
hit test -> UIApplication ->UIWindow -> UIViewController -> UIView -> UISubView -> ...
事件的传递顺序与之相反
常见UIView不响应事件的处理有哪些
1.view.userInteractionEnabled = NO;
2.view.hidden = YES;
3.view.alpha < 0.05;
4.view 超过superView的bounds;
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *blueView;
@property (strong, nonatomic) CALayer *layer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_layer = [CALayer layer];
_layer.frame = CGRectMake(0, 0, 30, 30);
_layer.backgroundColor = [UIColor greenColor].CGColor;
[_blueView.layer addSublayer:_layer];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint point = [[touches anyObject]locationInView:self.view];
CALayer *layer = [self.view.layer hitTest:point];
if (layer == self.layer){
NSLog(@"layer.....");
}else if (layer == self.blueView.layer){
NSLog(@"blueView.layer...");
}else{
NSLog(@"self.view.layer....");
}
}
-
CALayer -- 仿射变换
DB1A03F6-8591-4D08-B46B-147AE4E4EDD6.png
//沿y轴旋转90°
CATransform3D transform3D = CATransform3DIdentity;
transform3D.m34 = -1.0/500.0;
transform3D = CATransform3DRotate(transform3D, M_PI_4, 1, 1, 1);
_iconImageView.layer.transform = transform3D;
//正背面渲染 --> 渲染技术正背面剔除,判断用户可见/不可见,layer在旋转180°之后的一个正背面渲染是否可见的操作
_iconImageView.layer.doubleSided = NO;
//在一个父亲视图中有两个子视图的旋转
![](https://img.haomeiwen.com/i3484821/479cb19d112da2be.png)
//CATransform3D画立体的正方体,xib中的view的大小为(100,100)
@interface SeconedViewController ()
@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 (strong, nonatomic)NSArray *array;
@end
@implementation SeconedViewController
- (void)viewDidLoad {
[super viewDidLoad];
_array = @[_view0,_view1,_view2,_view3,_view4,_view5];
CATransform3D transform3D = CATransform3DIdentity;
transform3D.m34 = -1.0/500.0;
self.view.layer.sublayerTransform = CATransform3DRotate(transform3D, -M_PI_4, 1, 1,0);
//面对用户的view
CATransform3D transform0 = CATransform3DMakeTranslation(0, 0, 50);
[self addFace:0 withTransform:transform0];
//顶部的view
CATransform3D transform1 = CATransform3DMakeTranslation(0, -50, 0);
transform1 = CATransform3DRotate(transform1, M_PI_2, 1,0, 0);
[self addFace:1 withTransform:transform1];
CATransform3D transform2 = CATransform3DMakeTranslation(50, 0, 0);
transform2 = CATransform3DRotate(transform2, -M_PI_2, 0, 1, 0);
[self addFace:2 withTransform:transform2];
CATransform3D transform3 = CATransform3DMakeTranslation(0, 0, -50);
[self addFace:4 withTransform:transform3];
}
- (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform{
UIView *view = _array[index];
[self.view addSubview:view];
CGRect rect = self.view.bounds;
view.center = CGPointMake(rect.size.width/2.0, rect.size.height/2.0);
view.layer.transform = transform;
}
*CAShaperLayer
//画火柴人
UIBezierPath *path = [UIBezierPath new];
[path addArcWithCenter:CGPointMake(100, 100) radius:50.0 startAngle:0 endAngle:2*M_PI clockwise:YES];
[path moveToPoint:CGPointMake(100, 150)];
[path addLineToPoint:CGPointMake(100, 300)];
[path moveToPoint:CGPointMake(100, 170)];
[path addLineToPoint:CGPointMake(60, 200)];
[path moveToPoint:CGPointMake(100, 170)];
[path addLineToPoint:CGPointMake(140, 200)];
[path moveToPoint:CGPointMake(100, 300)];
[path addLineToPoint:CGPointMake(60, 330)];
[path moveToPoint:CGPointMake(100, 300)];
[path addLineToPoint:CGPointMake(140, 330)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
//画笔的颜色
shapeLayer.strokeColor = [UIColor redColor].CGColor;
//填充色
shapeLayer.fillColor = [UIColor whiteColor].CGColor;
//画笔的宽度
shapeLayer.lineWidth = 5;
//连接方式
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.path = path.CGPath;
[self.view.layer addSublayer:shapeLayer];
//切圆角
![](https://img.haomeiwen.com/i3484821/c3794bcf3cf7c129.png)
- CATextLayer
CATextLayer *textLayer = [CATextLayer layer];
textLayer.frame = CGRectMake(10, 100, self.view.frame.size.width-20, 100);
[self.view.layer addSublayer:textLayer];
//设置文字颜色
textLayer.foregroundColor = [UIColor redColor].CGColor;
//设置对齐方式
textLayer.alignmentMode = kCAAlignmentLeft;
//环绕
textLayer.wrapped = YES;
//Retina屏幕像素渲染
textLayer.contentsScale = [UIScreen mainScreen].scale;
//设置字体
UIFont *font = [UIFont systemFontOfSize:15];
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
textLayer.font = fontRef;
textLayer.fontSize = font.pointSize;
//释放
CGFontRelease(fontRef);
textLayer.string = @"测试,啦啦啦啦啦啦";
- CATransformLayer
- (void)viewDidLoad {
[super viewDidLoad];
CATransform3D transform3D = CATransform3DIdentity;
transform3D.m34 = -1.0/500.0;
self.view.layer.sublayerTransform = CATransform3DRotate(transform3D, -M_PI_4, 1, 1, 0);
[self.view.layer addSublayer:[self addTransform]];
}
- (CALayer *)addTransform{
CATransformLayer *transformLayer = [CATransformLayer layer];
CATransform3D transform0 = CATransform3DMakeTranslation(0, 0, 50);
[transformLayer addSublayer:[self createLayer:transform0]];
CATransform3D transform1 = CATransform3DMakeTranslation(0, -50, 0);
transform1 = CATransform3DRotate(transform1, -M_PI_2, 1, 0, 0);
[transformLayer addSublayer:[self createLayer:transform1]];
CATransform3D transform2 = CATransform3DMakeTranslation(50, 0, 0);
transform2 = CATransform3DRotate(transform2, M_PI_2, 0, 1, 0);
[transformLayer addSublayer:[self createLayer:transform2]];
CGSize containerSize = self.view.bounds.size;
transformLayer.position = CGPointMake(containerSize.width/2.0, containerSize.height/2.0);
return transformLayer;
}
- (CALayer *)createLayer:(CATransform3D)transform{
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
CGFloat read = (rand()/(double)INT_MAX);
CGFloat green = (rand()/(double)INT_MAX);
CGFloat blue = (rand()/(double)INT_MAX);
layer.backgroundColor = [UIColor colorWithRed:read green:green blue:blue alpha:1.0].CGColor;
layer.transform = transform;
return layer;
}
- CAGradientLayer
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(10, 120, self.view.frame.size.width - 20, 100);
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor greenColor].CGColor,(__bridge id)[UIColor blueColor].CGColor];
//设置颜色的的占比
gradientLayer.locations = @[@0.01,@0.79,@0.2];
//开始位置
gradientLayer.startPoint = CGPointMake(0, 0);
//结束位置
gradientLayer.endPoint = CGPointMake(1, 1);
[self.view.layer addSublayer:gradientLayer];
- CARelicatorLayer
CAReplicatorLayer *layer = [CAReplicatorLayer layer];
//设置复制层中的总层数,包含原生层
layer.instanceCount = 2;
CATransform3D transform3D = CATransform3DIdentity;
//间隔
CGFloat number = _IconImageView.bounds.size.height + 2;
transform3D = CATransform3DTranslate(transform3D, 0, number, 0);
transform3D = CATransform3DScale(transform3D, -1, -1, 0);
layer.instanceTransform = transform3D;
//修改t透明度
layer.instanceAlphaOffset = -0.75;
- CAEmitterLayer&CAEmitterCell
#import "NinthViewController.h"
@interface NinthViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelTopLayout;
@property (nonatomic, strong)CAEmitterLayer *layer;
@end
@implementation NinthViewController
- (void)viewDidLoad {
[super viewDidLoad];
if(UIApplication.sharedApplication.statusBarFrame.size.height > 20){
_labelTopLayout.constant = 88;
}
//1.创建发射源
CAEmitterLayer *layer = [CAEmitterLayer layer];
[self.view.layer addSublayer:layer];
_layer = layer;
//发射源尺寸
layer.emitterSize = self.view.frame.size;
//发射源的形状
layer.emitterShape = kCAEmitterLayerPoint;
//发射模式
layer.emitterMode = kCAEmitterLayerPoints;
//l粒子发射的中心点
layer.emitterPosition = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height);
//2.设置cell(粒子的样式)
CAEmitterCell *cell = [CAEmitterCell emitterCell];
cell.name = @"cell";
//粒子的产生率
cell.birthRate = 20.0f;
//粒子的生命周期
cell.lifetime = 10.0f;
//粒子速度
cell.velocity = 40.0f;
cell.velocityRange = 100.0;
//在y轴上面的加速度
cell.yAcceleration = -15.0f;
//发射的范围
cell.emissionLatitude = 0;
cell.emissionRange = M_PI;
//缩放
cell.scale = 0.2;
cell.scaleRange = 0.1;
cell.scaleSpeed = 0.02;
//粒子的内容
cell.contents =(id)[[UIImage imageNamed:@"yuandian"]CGImage];
//颜色变化
cell.color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0].CGColor;
//粒子颜色改变范围
cell.alphaRange = 0.8;
cell.redRange = 1.0f;
cell.greenRange =1.0f;
//粒子变化的速度
cell.blueSpeed = 1.0f;
cell.alphaRange = -0.1f;
layer.emitterCells = @[cell];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint point = [self loacationFromTouchEvent:event];
[self setBallInPsition:point];
}
- (CGPoint)loacationFromTouchEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches]anyObject];
return [touch locationInView:self.view];
}
- (void)setBallInPsition:(CGPoint)position{
//粒子放大过程
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"emitterCells.cell.scale"];
animation.fromValue = @0.2;
animation.toValue = @0.5;
animation.duration = 1.0;
//线性变化
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
//移动粒子的发射位置
[CATransaction begin];
[CATransaction setDisableActions:YES];
[_layer addAnimation:animation forKey:nil];
[_layer setValue:[NSValue valueWithCGPoint:position] forKey:@"emitterPosition"];
[CATransaction commit];
}
@end
//下雨的效果
#import "TenViewController.h"
@interface TenViewController ()
@property (nonatomic, strong)CAEmitterLayer *layer;
@end
@implementation TenViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createRainLayer];
}
- (void)createRainLayer{
//创建发射源
CAEmitterLayer *layer = [CAEmitterLayer layer];
_layer = layer;
[self.view.layer addSublayer:layer];
//发射中心
layer.emitterPosition = CGPointMake(self.view.bounds.size.width/2.0+20, -10);
//设置发射属性
layer.emitterShape = kCAEmitterLayerLine;
layer.emitterMode = kCAEmitterLayerLine;
//发射源尺寸
layer.emitterSize = self.view.frame.size;
//创建发射粒子
CAEmitterCell *cell = [CAEmitterCell emitterCell];
//设置粒子图片背景
cell.contents = (id)[[UIImage imageNamed:@"rain"]CGImage];
//设置粒子产生率
cell.birthRate = 80.0f;
//设置粒子生命周期
cell.lifetime = 20.0f;
//设置粒子的加速度
cell.speed = 1.0f;
//设置粒子速度
cell.velocity = 10.0f;
cell.velocityRange = 10.0f;
//设置粒子在y轴上面的加速度
cell.yAcceleration = 100;
//设置粒子的缩放
cell.scale = 0.1;
layer.emitterCells = @[cell];
}
//开始或者停止下雨
- (IBAction)beginRainButtonClick:(UIButton *)sender {
if (sender.selected) {
NSLog(@"开始下雨");
[sender setTitle:@"开始下雨" forState:UIControlStateNormal];
[_layer setValue:@1.0f forKey:@"birthRate"];
}else{
NSLog(@"停止下雨");
[sender setTitle:@"停止下雨" forState:UIControlStateNormal];
[_layer setValue:@0.0f forKey:@"birthRate"];
}
sender.selected = ! sender.selected;
}
//下大雨
- (IBAction)BigRainButtonClick:(UIButton *)sender {
float rate = 1;
float scale = 0.1;
if (_layer.birthRate <= 80 ){
[_layer setValue:@(_layer.birthRate + rate) forKey:@"birthRate"];
[_layer setValue:@(_layer.scale + scale) forKey:@"scale"];
}
}
//下小雨
- (IBAction)SamllRainButtonClick:(UIButton *)sender {
float rate = 1;
float scale = 0.1;
if (_layer.birthRate >= 1 ){
[_layer setValue:@(_layer.birthRate - rate) forKey:@"birthRate"];
[_layer setValue:@(_layer.scale - scale) forKey:@"scale"];
}
}
@end
网友评论