项目效果
CALay属性mask
我们可以比较简单地通过masksToBounds属性沿边界裁剪图形,通过cornerRadius属性设定一个圆角,但当遇到展现的内容不是一个规则的圆或者矩形的时候,例如,一个有星形的图片。此时,我们便可以使用CALayer的mask属性去实现图层遮罩。
@property(nullable, strong) CALayer *mask;
可以看到mask属性本身就是一个CALayer类型,除此之外,mask属性定义了父图层的部分可见区域。当mask图层比父图层小的时候,此时便会只展现mask图层里面的内容,mask图层以外的图层的内容会被隐藏(不显示)。
- 简单展示mask属性的简单使用
创建项目,在storyBoard中添加一个UIImageView,添加相应约束(水平方向、垂直方向居中显示、固定宽高为60),拖入相关资源图片。
1.创建CALayer实例maskLayer
CALayer *maskLayer = [CALayer layer];
2.设置maskLayer的contents属性(需要CGImageRef类型)
maskLayer.contents = (__bridge id) [UIImage imageNamed:@"logo"].CGImage;
3.设置maskLayer属性的frame
maskLayer.frame = self.imageView.bounds;
4.设置mask遮罩
self.imageView.layer.mask = maskLayer;
最后comm + R,你会看到星形的图片已经很顺利的生成了。
5.星形效果
那要完成前文的效果还需要其他什么动画知识呢?CAKeyframeAnimation(关键帧动画)你值得拥有。
CAKeyframeAnimation
CAKeyframeAnimation为图层对象提供了关键帧动画的能理,其可以指定keyframe的值去控制动画的时间和动画的行为。
- 常用属性介绍
1.创建CAKeyframeAnimation对象
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
通过设置方法的参数path去设置动画的keyPath属性
2.设置动画的时间
@property CFTimeInterval duration;
3.设置动画开始的时间
@property CFTimeInterval beginTime;
4.设置每一关键帧的值
@property(nullable, copy) NSArray *values;
5.设置一个关键帧到另一个关键帧的时间(值为0-1)
@property(nullable, copy) NSArray *timingFunctions;
介绍完常用属性,那么就开始我们的项目吧。
项目效果的实现
该项目是一个较为简单的启动动画效果。前面我们已经较为顺利地使用mask属性去得到了星形的图片,那么我在此基础上修改我们的代码,实现效果。准备工作
1.新建工程,拖入相关的资源图片。在storyboard界面,给控制器Embed In一个Navigation Controller。并在ViewController中拖入一个UIImageView控件并设置约束(top、left、bottom、right与父视图重合),设置image属性。
2.在LaunchScreen.storyboard中拖入UIIimageView并设置约束(水平、垂直方向均保持居中,固定宽高为60),设置背景颜色为橘黄色,并设置图片的image为星形图片
3.在application: didFinishLaunchingWithOptions:方法中进行相关动画(实际开发中可将动画代码写在自定义类中方便管理)实现思路
我们已经在LaunchScreen.storyboard设置好了启动时的星形图片,而在项目效果图中,我们可以看到启动图片消失后,星形图片依然存在。因此我们可以在ViewController的view中添加一个星形的mask遮罩,并将其位置设置为与启动图中的星形图片的位置相同。然后再对控制器的view的mask进行动画操作。代码分解
使用UIStoryboard的相关方法获取UINavigationController
UINavigationController *naVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateInitialViewController];
self.window.rootViewController = naVC;
- 实现星形遮罩
CALayer *maskLayer = [CALayer layer];
maskLayer.contents = (__bridge id)[UIImage imageNamed:@"logo"].CGImage;
maskLayer.position = naVC.view.center;
maskLayer.bounds = CGRectMake(0, 0, 60, 60);
naVC.view.layer.mask = maskLayer;
此时启动应用,我们会发现启动图片消失后,除了星形图片以外,其他的界面并不是我们效果中的橘黄色而是黑色,产生这个问题的原因是window的背景颜色为黑色,那么我们就简单粗暴地去解决这个问题,直接设置window的背景颜色和启动界面的背景颜色相同。
self.window.backgroundColor = [UIColor orangeColor];
从效果图中可以看到控制器中星形的内容是逐渐可见的,而到上一步我们的效果是启动界面结束后,就直接看到了星形的内容。因此我们做进一步处理。
创建一个白色的view对控制器的内容进行遮罩,并缓慢消失最后移除。
UIView *whiteView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
whiteView.backgroundColor = [UIColor whiteColor];
[naVC.view addSubview:whiteView];
[naVC.view bringSubviewToFront:whiteView];
[UIView animateWithDuration:0.1 delay:1 options:UIViewAnimationOptionCurveEaseIn animations:^{
whiteView.alpha = 0;
} completion:^(BOOL finished) {
[whiteView removeFromSuperview];
}];
- 为mask图层添加关键帧动画
CAKeyframeAnimation *maskLayerAnimation = [CAKeyframeAnimation animationWithKeyPath:@"bounds"];
maskLayerAnimation.duration = 1;
maskLayerAnimation.beginTime = CACurrentMediaTime() + 1.0f;//延迟一秒
CGRect startRect = maskLayer.frame;
CGRect tempRect = CGRectMake(0, 0, 100, 100);
CGRect finalRect = CGRectMake(0, 0, 2000, 2000);
maskLayerAnimation.values = @[[NSValue valueWithCGRect:startRect], [NSValue valueWithCGRect:tempRect], [NSValue valueWithCGRect:finalRect]];maskLayerAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
// 默认情况下动画结束后会回到初始状态,设置下面的两个属性可使动画结束后不回到初始位置并保持最后的状态
maskLayerAnimation.removedOnCompletion = NO;
maskLayerAnimation.fillMode = kCAFillModeForwards;
// 为图层添加动画效果
[naVC.view.layer.mask addAnimation:maskLayerAnimation forKey:@"logoMaskAnimaiton"];
- 对控制器的内容进行简单的缩放
[UIView animateWithDuration:0.25 delay:1.3 options:UIViewAnimationOptionTransitionNone animations:^{
naVC.view.transform = CGAffineTransformMakeScale(1.05, 1.05);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
naVC.view.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
naVC.view.layer.mask = nil;
}];
}];
最后,command + R看看效果吧。
tips:为了使动画衔接完整,多调试各个动画的动画时间
向KITTEN
本文GitHub地址:
https://github.com/RookieAngry/Demo_CAKeyframeAnimation.git
项目来源于KITTEN大神的《A GUIDE TO IOS ANIMATION》