在项目需求中往往有这样一种场景,需要做半透明的视图,一般的情形可能会想到做一个中间层的view,设置它的透明度,这样就可以达到这种效果,但从了解了用贝塞尔曲线画出来之后,就觉得用view去实现有些Low了,这里就简单介绍如何用贝塞尔曲线去画半透明图片
1.画半透明的矩形
- (UIImage *)getOpaueImage {
UIImage *opaueImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
//获得当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath];
//设置矩形绘图路径
[path moveToPoint:CGPointMake(0, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height)];
[path addLineToPoint:CGPointMake(0, self.frame.size.height)];
[path addLineToPoint:CGPointMake(0, 0)];
//绘制
CGContextAddPath(ctx, path.CGPath);
//设置填充颜色
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.8] setFill];
CGContextFillPath(ctx);
//获取画的图片
opaueImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return opaueImage;
}
//这里主要的是贝塞尔曲线路径的设置
绘制步骤不难,下面再介绍一种带圆角的矩形,至于圆角设置,看具体需求,这里以右侧半圆弧为例
2.绘制带弧度的矩形图片
- (UIImage *)getRectWithCorner {
UIImage *opaueImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size,NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width - self.frame.size.height / 2, 0)];
//添加弧度
[path addArcWithCenter:CGPointMake(self.frame.size.width - self.frame.size.height / 2, self.frame.size.height / 2) radius:self.frame.size.height / 2 startAngle:3 * M_PI / 2 endAngle:5 * M_PI / 2 clockwise:YES];
[path addLineToPoint:CGPointMake(0, self.frame.size.height)];
[path addLineToPoint:CGPointMake(0, 0)];
CGContextAddPath(context, path.CGPath);
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5] setFill];
CGContextFillPath(context);
opaueImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return opaueImage;
}
实现起来其实很简单,主要的就是路径的设置
3.学习了上面两种之后,在项目需求里有一种视图是左边是选中和非选中状态的圆环,右边是数字,第一感觉是可以用button,左边放图片右边放数字,这样也是可以的,其实用贝塞尔曲线也是可以实现的,具体步骤如下
.h中
#import <UIKit/UIKit.h>
@interface WNSelectedButton : UIButton
@property (nonatomic,copy) NSString *title;
@end
.m中
#import "WNSelectedButton.h"
@implementation WNSelectedButton
- (void)setTitle:(NSString *)title {
_title = title;
[self setNeedsDisplay];//重新绘制
}
//进行绘制
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
if (self.selected) {
UIImage *selectedImage = [self selectedImage];
[selectedImage drawInRect:rect];
}else {
UIImage *normalImage = [self normalImage];
[normalImage drawInRect:rect];
}
UIFont *font = [UIFont systemFontOfSize:ScaleToScreenW(12)];
CGSize size = [self.title sizeWithAttributes:@{NSFontAttributeName:font}];
[self.title drawInRect:CGRectMake(20,rect.size.height * 0.5 - size.height / 2, rect.size.width - 20, rect.size.height) withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName:[UIColor whiteColor]}];
}
//正常状态下的图片
- (UIImage *)normalImage {
UIImage *normalImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(6, self.frame.size.height * 0.5) radius:5 startAngle:0 endAngle:2 * M_PI clockwise:YES];
CGContextAddPath(ctx, circlePath.CGPath);
[[UIColor whiteColor] setStroke];
CGContextSetLineWidth(ctx, 1.0);
CGContextStrokePath(ctx);
normalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalImage;
}
//选中状态下的图片
- (UIImage *)selectedImage {
UIImage *selectedImage;
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
//先画外圆
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(6, self.frame.size.height * 0.5) radius:5 startAngle:0 endAngle:2 * M_PI clockwise:YES];
CGContextAddPath(ctx, circlePath.CGPath);
[[UIColor colorFromHexRGB:@"#da4a4a"] setStroke];
CGContextSetLineWidth(ctx, 1.0);
CGContextStrokePath(ctx);
//再画内圆
UIBezierPath *centerPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(6, self.frame.size.height * 0.5) radius:2 startAngle:0 endAngle:2 * M_PI clockwise:YES];
CGContextAddPath(ctx, centerPath.CGPath);
[[UIColor colorFromHexRGB:@"#da4a4a"] setFill];
CGContextFillPath(ctx);
selectedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return selectedImage;
}
@end
其实也不难理解,自己尝试几次就可以掌握其中的关窍,这是贝塞尔曲线结合CG框架实现的,在tableView的cell中如果有相关圆角或者圆形图片的处理,都可以考虑这种实现方式,可以极大地优化tableView的卡顿问题