设置控件进行3D过渡转换
注:UIView只能进行2D转换使用的是CGATransform,layer是CATransform
// 注意 layer转换效果(旋转,缩放,等)都是根据锚点执行的
_image.layer.transform = CATransform3DRotate(_image.layer.transform, M_PI, 1, 1, 0);
layer显示图片
注:UIView中center就是layer中的position 是根据UIView.layer,anchorPoint锚点来定位的
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(100, 100, 100, 100);
// layer也可以添加图片到内容区 contents 但是需要CGImageRef类型的结构体
layer.contents = (id)[UIImage imageNamed:@"timg"].CGImage;
layer - position(定位) 和 anchorPoint(锚点)
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor purpleColor].CGColor;
// 锚点默认是0.5,0.5 (中心)
// 修改锚点不会调整position 只会修改UIView的frame.origin和center , UIView的frame和center是由锚点和position算出来的.这两个属性修改互不干扰。
// 设置锚点的位置 自身横、纵坐标为1 (0.5,0.5)为中心 0,0为左上角
layer.anchorPoint = CGPointMake(0.5, 0.5);
layer.position = self.view.center;
[self.view.layer addSublayer:layer];
- 锚点距离父控件坐标系的位置是position !!! (
注意看句子的顺序
),center是控件的中心点位置,center和frame都是由锚点和position计算出来的- 锚点和center修改互不相干,互相不会影响对方的值,只会影响frame和center.
layer隐式动画
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
[self.view.layer addSublayer:layer];
layer.backgroundColor = [UIColor purpleColor].CGColor;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// layer的属性注释带有Animatable的都是带有隐式动画的 直接修改数值就会产生动画
// layer的动画都是被包装成一个CATransaction事务执行的
[CATransaction begin];
// 设置layer隐式动画的持续时间
[CATransaction setAnimationDuration:2];
// 关闭事务 禁止隐式动画执行
// [CATransaction setDisableActions:YES];
layer.anchorPoint = CGPointMake(0.5, 0.5);
layer.position = self.view.center;
self.view.backgroundColor = [UIColor grayColor];
[CATransaction commit];
});
}
CA动画
// 创建基础动画类
CABasicAnimation *ani = [CABasicAnimation animation];
ani.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
ani.keyPath = @"transform.translation";
// 动画执行完毕后不要删除动画
ani.removedOnCompletion = NO;
// 动画缓动函数
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
// 动画结束后始终保持最后执行的效果
ani.fillMode = kCAFillModeForwards;
ani.duration = 0.8;
//重复执行次数
ami.repeatCount = MAXFLOAT;
//是否回放动画
ami.autoreverses = YES;
// 帧动画
//注意 结果必须是浮点型 也就是说必须是180.0 如果是180*传入的整型5则*M_PI返回的也是整型
#define angle2Rad(angle) (angle / 180.0 * M_PI)
CAKeyframeAnimation *ani = [CAKeyframeAnimation animation];
// 传入多个value 每个value表示一帧
ani.values = @[@(angle2Rad(-5)),@(angle2Rad(5)),@(angle2Rad(-5))];
ani.keyPath = @"transform.rotation";
ani.duration = 0.25;
ani.repeatCount = MAXFLOAT;
[_image.layer addAnimation:ani forKey:nil];
//帧动画可以使用path来设置动画移动轨迹
CAKeyframeAnimation *ani = [CAKeyframeAnimation animation];
ani.path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 200)].CGPath;
ani.keyPath = @"transform.translation";
ani.duration = 0.25;
ani.repeatCount = MAXFLOAT;
[_image.layer addAnimation:ani forKey:nil];
CA切换(转场)动画
动画type值
_image.image = [UIImage imageNamed:[NSString stringWithFormat:@"%i",(_i%3)+1]];
CATransition *transtion = [CATransition animation];
transtion.type = @"rippleEffect";
transtion.duration = 0.8;
[_image.layer addAnimation:transtion forKey:nil];
}
UIView也有类似CA的切换(转场)动画 但是转场类型比较少
[UIView transitionWithView:_image duration:0.8 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
_i++;
_image.image = [UIImage imageNamed:[NSString stringWithFormat:@"%i",(_i%3)+1]];
} completion:nil];
动画组
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
CABasicAnimation *ani1 = [CABasicAnimation animation];
ani1.toValue = [NSValue valueWithCGPoint:CGPointMake(0.5, 0.5)];
ani1.keyPath = @"transform.scale";
CABasicAnimation *ani2 = [CABasicAnimation animation];
ani2.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
ani2.keyPath = @"transform.translation";
// 动画缓动函数
ani2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
group.animations = @[ani1,ani2];
// 动画执行完毕后不要删除动画
group.removedOnCompletion = NO;
// 动画结束后始终保持最后执行的效果
group.fillMode = kCAFillModeForwards;
group.duration = 0.8;
[_image.layer addAnimation:group forKey:nil];
图片折叠效果
- (void)viewDidLoad {
[super viewDidLoad];
_topImageV.layer.anchorPoint = CGPointMake(0.5, 1);
// 设置imageView里的图片内容展示范围
// 从x0y0开始一个宽度满高度为一半的矩形截取内容图片然后填充imageView显示
_topImageV.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);
_bottomImagev.layer.anchorPoint = CGPointMake(0.5, 0);
// 从x0y一半开始一个宽度满高度为一半的矩形截取内容图片然后填充imageView显示
_bottomImagev.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);
}
- (IBAction)draging:(UIPanGestureRecognizer *)sender {
CATransform3D transform = CATransform3DIdentity;
// 设置矩阵的立体效果
transform.m34 = -1 / 500.0;
if (sender.state == UIGestureRecognizerStateEnded) {
CABasicAnimation *ani = [CABasicAnimation animation];
ani.toValue =@0;
ani.keyPath = @"transform.rotation.x";
ani.removedOnCompletion = NO;
ani.fillMode = kCAFillModeForwards;
ani.duration = 0.3;
ani.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[_topImageV.layer addAnimation:ani forKey:nil];
}else{
[_topImageV.layer removeAllAnimations];
CGFloat moveNum = [sender translationInView:sender.view].y;
// 防止折叠刀下部分图片下面
CGFloat angle = moveNum / 256.0 * M_PI;
angle = angle < M_PI?angle:0.99*M_PI;
// 设置矩阵旋转绕着x轴旋转
_topImageV.layer.transform = CATransform3DRotate(transform, -angle, 1, 0, 0);}
}
渐变层CAGradientLayer使用
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.colors = @[(id)[UIColor blackColor].CGColor,(id)[UIColor clearColor].CGColor ];
gradient.startPoint = CGPointMake(0.5, 1);
gradient.endPoint = CGPointMake(0.5, 0);
// 设置渐变层大小
gradient.frame = _bottomImagev.bounds;
gradient.opacity = 0;
[_bottomImagev.layer addSublayer:gradient];
复制层CAReplicatorLayer使用
CAReplicatorLayer *repl = [CAReplicatorLayer layer];
repl.frame = _contentV.bounds;
[_contentV.layer addSublayer:repl];
repl.instanceCount = 3;
// 相对上个实例动画延迟时间
repl.instanceDelay = 0.2;
// 相对上个实例形变
repl.instanceTransform = CATransform3DMakeTranslation(35, 0, 0);
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.bounds = CGRectMake(0, 0, 20, 80);
layer.anchorPoint = CGPointMake(0, 1);
layer.position = CGPointMake(0, _contentV.bounds.size.height);
CABasicAnimation *ani = [CABasicAnimation animation];
ani.toValue = @0;
ani.keyPath = @"transform.scale.y";
ani.repeatCount = MAXFLOAT;
ani.autoreverses = YES;
ani.duration = 0.2;
[layer addAnimation:ani forKey:nil];
[repl addSublayer:layer ];
网友评论