最近發(fā)現(xiàn)CALayer能實(shí)現(xiàn)的東西有很多,而且都很有意思吭从,效果不錯(cuò)朝蜘。今天寫了一個(gè)遮罩的和一個(gè)圖片漸變的功能。
先看效果涩金。
跟舞臺(tái)的聚光燈一樣 隨著時(shí)間移來移去的谱醇,遮罩住其他的地方。
直接上代碼了鸭廷。
```
@interface MaskViewController ()
@property (nonatomic, strong) CALayer *imageLayer;
@property (nonatomic, strong) CALayer *maskLayer;
@property (nonatomic, strong) UIImage *imageContents;
@property (nonatomic, strong) UIImage *maskContents;
@end
@implementation MaskViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
self.imageContents = [UIImage imageNamed:@"開始圖片.jpg"];
self.maskContents = [UIImage imageNamed:@"maskLayerContents"];
//圖片layer
self.imageLayer = [CALayer layer];
self.imageLayer.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64);
self.imageLayer.contents = (__bridge id _Nullable)(self.imageContents.CGImage);
[self.view.layer addSublayer:self.imageLayer];
//遮罩layer
self.maskLayer = [CALayer layer];
self.maskLayer.frame = CGRectMake(0, 64, 200, 200);
self.maskLayer.contents = (__bridge id _Nullable)(self.maskContents.CGImage);
//? ? 這個(gè)不用圖片也可以 用背景顏色 例如下面這段? 但是效果沒圖片那樣好看
//? ? self.maskLayer.backgroundColor = [UIColor blackColor].CGColor;
//? ? self.maskLayer.cornerRadius = 100;
//? ? self.maskLayer.masksToBounds = YES;
//? ? An optional layer whose alpha channel is used to mask the layer’s content.
//? ? 根據(jù)alpha通道 來選擇遮罩的地方 黑色全通過枣抱,白色全不通過
self.imageLayer.mask = self.maskLayer;
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(maskLayerAnimation:) userInfo:nil repeats:YES];
}
- (void)maskLayerAnimation:(NSTimer *)timer{
//要顯示的區(qū)域可以自己在設(shè)定一下
CGFloat x = arc4random() % (375-200);
CGFloat y = arc4random() % (667-200-64);
self.maskLayer.frame = CGRectMake(x, y, 200, 200);
}
```
注釋都有 另外還有一個(gè)圖片的出現(xiàn)消失的組合動(dòng)畫,代碼如下
#define ISSHOW YES
@interface ChangeViewController ()
@property (nonatomic, strong) CALayer *imageLayer;
@end
@implementation ChangeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIImage *image1 = [UIImage imageNamed:@"開始圖片.jpg"];
//? ? self.view.layer.contents = (__bridge id _Nullable)(image.CGImage);
//? ? 只要有前面這兩句就可以顯示圖片了辆床,可以得出layer是圖片的載體 UIimageView可能是充分的利用了這個(gè)屬性
//創(chuàng)建出圖片的layer
self.imageLayer = [CALayer layer];
self.imageLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view.layer addSublayer:self.imageLayer];
//? ? 將圖片加載到layer的contents
self.imageLayer.contents = (__bridge id _Nullable)(image1.CGImage);
[self performSelector:@selector(layerAnimation) withObject:nil afterDelay:3.0];
}
- (void)layerAnimation{
UIImage *image2 = [UIImage imageNamed:@"結(jié)束圖片.jpg"];
//隱式動(dòng)畫 比沒有流暢仔細(xì)看
if (!ISSHOW) {
self.imageLayer.contents = (__bridge id _Nullable)(image2.CGImage);
}
else{
//? ? keyPath就是imageLayer的contents屬性? 這個(gè)是圖片動(dòng)畫
CABasicAnimation *contentsAnimation = [CABasicAnimation animationWithKeyPath:@"contents"];
//? ? 起始圖片
contentsAnimation.fromValue = self.imageLayer.contents;
//? ? 結(jié)束圖片
contentsAnimation.toValue = (__bridge id _Nullable)(image2.CGImage);
//? ? 持續(xù)時(shí)間
contentsAnimation.duration = 2.0f;
//? ? bounds動(dòng)畫
CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
//? ? 因?yàn)閎ounds是CGRect類型 不是對(duì)象 所以要轉(zhuǎn)一下
boundsAnimation.fromValue = [NSValue valueWithCGRect:self.imageLayer.bounds];
boundsAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(self.view.frame.size.width / 4, self.view.frame.size.width / 4, self.view.frame.size.width / 2, self.view.frame.size.height / 2)];
boundsAnimation.duration = 2.0f;
//將動(dòng)畫組合起來
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = @[contentsAnimation,boundsAnimation];
groupAnimation.duration = 2.0f;
//? ? 執(zhí)行完之后又會(huì)回到原來的狀態(tài)佳晶,因?yàn)閘ayer只是提交了動(dòng)畫,并沒有修改layer的內(nèi)容? 只是一段過程 所以結(jié)束了之后要設(shè)定layer的內(nèi)容
self.imageLayer.contents = (__bridge id _Nullable)(image2.CGImage);
self.imageLayer.bounds = CGRectMake(self.view.frame.size.width / 4, self.view.frame.size.width / 4, self.view.frame.size.width / 2, self.view.frame.size.height / 2);
[self.imageLayer addAnimation:groupAnimation forKey:nil];
}
}
@end
進(jìn)度條代碼如下:
@interface ProgressViewController ()
@property (nonatomic, strong) ProgressView *progressView;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation ProgressViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.progressView = [[ProgressView alloc] initWithFrame:CGRectMake(20, 300, 300, 3)];
//設(shè)置進(jìn)度條顏色
self.progressView.layerColor = [UIColor blueColor];
//設(shè)置邊框大小
self.progressView.layer.borderWidth = 1.0;
//設(shè)置邊框顏色
//? ? self.progressView.layer.borderColor = [UIColor redColor].CGColor;
[self.view addSubview:self.progressView];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(layerAnimation) userInfo:nil repeats:YES];
}
- (void)layerAnimation{
//模擬下載進(jìn)度
self.progressView.progress = arc4random() %100 / 100.f;
}
@end
.h
@interface ProgressView : UIView
@property (nonatomic, assign) CGFloat progress;//進(jìn)度參數(shù)
@property (nonatomic, strong) UIColor *layerColor;//顏色
@end
.m
@interface ProgressView()
@property (nonatomic, strong) CALayer *progressLayer;
//這個(gè)記錄當(dāng)前這個(gè)進(jìn)度條的寬度
@property (nonatomic, assign) CGFloat currentWidth;
@end
@implementation ProgressView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//? ? ? ? 如果是用View自帶的layer設(shè)置則不會(huì)有隱式動(dòng)畫
//? ? ? ? 創(chuàng)建出一個(gè)獨(dú)立的layer則有
self.progressLayer = [CALayer layer];
self.progressLayer.frame = CGRectMake(0, 0, 0, frame.size.height);
self.progressLayer.backgroundColor = [UIColor redColor].CGColor;
[self.layer addSublayer:self.progressLayer];
self.currentWidth = frame.size.width;
}
return self;
}
#pragma mark ----set get
@synthesize progress = _progress;
- (void)setProgress:(CGFloat)progress{
_progress = progress;
if (progress <= 0) {
self.progressLayer.frame = CGRectMake(0, 0, 0, self.frame.size.height);
}else if (progress <= 1){
//? ? ? ? 進(jìn)度 * 總寬度 得到對(duì)應(yīng)的寬度
self.progressLayer.frame = CGRectMake(0, 0, self.currentWidth * progress, self.frame.size.height);
}else{
self.progressLayer.frame = CGRectMake(0, 0, self.currentWidth, self.frame.size.height);
}
}
- (CGFloat)progress{
return _progress;
}
@synthesize layerColor = _layerColor;
- (void)setLayerColor:(UIColor *)layerColor{
_layerColor = layerColor;
self.progressLayer.backgroundColor = layerColor.CGColor;
}
- (UIColor *)layerColor{
return _layerColor;
}
@end
注意 遮罩圖片最好是有透明通道的讼载,沒有的話也可以用背景顏色來設(shè)置轿秧。
代碼參考了YouXianMing - 博客園大神寫的
希望可以幫助到有需要的人,感謝開源咨堤。