CAShapeLayer是个非常好用的类,配合UIBezierPath曲线可以做很多特殊的效果,而且在效率和内存占用上比自己重新绘制好很多。
利用遮罩效果画圆角
什么是遮罩效果?
顾名思义,就像是一个罩子盖在了一个图片上,这个图片只漏出了一部分。每个View持有的Layer属性里都有一个mask属性,用来给这个view添加遮罩效果。
需要注意,遮罩效果中设置遮罩颜色是不起作用的,遮罩部分显示的是底色(层级上距离这个view最近上一层view的底色,并不一定是父视图的颜色),透明度在此起作用。
我们可以尝试利用这个方式做一个只有左上和右下有圆角效果的view。
//切个圆角(为了展示颜色效果,我添加了一个背景图)
self.view.backgroundColor = [UIColor lightGrayColor];
//
UIView *yx_backView = [[UIView alloc] initWithFrame:CGRectMake(150, 150, 150, 150)];
yx_backView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:yx_backView];
//进行操作的视图,左下和右上
UIView *yx_showView = [[UIView alloc] initWithFrame:CGRectMake(40, 40, 80, 80)];
yx_showView.backgroundColor = [UIColor greenColor];
[yx_backView addSubview:yx_showView];
//切个圆角操作
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, yx_showView.bounds.size.width, yx_showView.bounds.size.height) byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(20, 20)];
CAShapeLayer *maskShaperLayer = [CAShapeLayer layer];
maskShaperLayer.path = maskPath.CGPath;
yx_showView.layer.mask = maskShaperLayer;
效果如图所示:
可以自行测试设置遮罩颜色和遮罩应该显示的颜色。
利用这个效果我们可以很轻松地设置特殊的圆角操作要求,当然,配合贝塞尔曲线可以做出各种形状的遮罩达到特殊效果。
做一个动画效果
这里用到了CADisplayLink,在做与UI有关的需要用到计时时,强烈建议使用CADisplayLink而不是NSTimer。这两者之间的不同请参照:https://zsisme.gitbooks.io/ios-/content/chapter11/frame-timing.html
类似于这样的一个动态填充效果。事实上,你可以按照这种方式做很多简单的填充,需要的仅仅是一张填充好的图片和一张未填充的图片。
//做个动画
UIImageView *yx_starView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"星_03"]];
yx_starView.frame = CGRectMake(50, 300, 100, 100);
[self.view addSubview:yx_starView];
UIImageView *yx_coverStarView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1_03"]];
yx_coverStarView.frame = CGRectMake(0, 0, 100, 100);
[yx_starView addSubview:yx_coverStarView];
self.starShapeLayer = [CAShapeLayer layer];
UIBezierPath *starPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 0, 0) cornerRadius:0];
_starShapeLayer.path = starPath.CGPath;
yx_coverStarView.layer.mask = _starShapeLayer;
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(yx_starAnimation)];
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
//填充百分比
self.starFillPercent = 0;
- (void)yx_starAnimation {
//假设要4秒填充完整个星星,每秒需要填充百分之25,CADisplayLink频率大概是1秒60次,这里不需要特别的精准,就不用时间偏移精确计算了
_starFillPercent += 0.25/60;
if (_starFillPercent > 1) {
[_displayLink invalidate];
return;
}
UIBezierPath *starPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 100,100,-_starFillPercent*100) cornerRadius:0];
_starShapeLayer.path = starPath.CGPath;
}