利用贝塞尔曲线画半透明图片

在项目需求中往往有这样一种场景,需要做半透明的视图,一般的情形可能会想到做一个中间层的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 

@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的卡顿问题

你可能感兴趣的:(利用贝塞尔曲线画半透明图片)