iOS绘图-UIBezierPath的使用

UIBezierPath简单介绍

    iOS系统本身提供了两套绘图的框架,即UIBezierPath 和 Core Graphics。使用UIBezierPath可以创建基于矢量的路径,此类是Core Graphics框架关于路径的封装,所以使用起来比较简单。使用此类可以定义简单的形状,如椭圆、矩形或者有多个直线和曲线段组成的形状等。UIBezierPath是CGPathRef数据类型的封装。如果是基于矢量形状的路径,都用直线和曲线去创建。我们使用直线段去创建矩形和多边形,使用曲线去创建圆弧(arc)、圆或者其他复杂的曲线形状。

    使用UIBezierPath,你只能在当前上下文中绘图,所以如果你当前处于UIGraphicsBeginImageContextWithOptions函数或drawRect:方法中,你就可以直接使用UIKit提供的方法进行绘图。我们一般使用UIBezierPath都是在重写的drawRect方法中实现。首先我们看UIBezierPath绘图的基本步骤:
  1. 重写drawRect方法,但不需要我们自己获取当前上下文
  2. 创建Bezier path对象并设置绘图相关属性
  3. 添加线或者曲线定义路径
  4. 渲染,完成绘制

UIBezierPath创建方法

UIBezierPath类提供了下面这些类方法创建路径:

+ (instancetype)bezierPath;
+ (instancetype)bezierPathWithRect:(CGRect)rect;
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
下面我们一个一个的简单介绍其用法:
    + (instancetype)bezierPath;
这个方法适用的范围比较广,适用此方法我们可以根据我们的的需要画出任意的图形。
    + (instancetype)bezierPathWithRect:(CGRect)rect;
这个方法根据传入的Rect参数画出一个矩形
    + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
这个方法根据一个矩形画内切的曲线,一般我们用它来画圆或者椭圆
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
这两个方法比较类似,两个类方法都可以画带有圆角的矩形,第一个参数是矩形,第二个参数是圆角大小,但是第二个方法可以指定把矩形某一个角画成圆角。
    + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
这个方法用于画弧线,center:弧线中心点的坐标 radius:弧线所在圆的半径 startAngle:弧线开始的角度 endAngle:弧线结束的角度 clockwise: 是否顺时针画弧线(YES表示顺时针 NO表示逆时针)

下面通过几段代码做个事例(注意下面代码都在- (void)drawRect:(CGRect)rect方法中实现)

画三角形

//绘制三角形
- (void)drawTriangle{
    //1. 创建UIBezierPath对象
    UIBezierPath *path = [UIBezierPath bezierPath];

    //2. 配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色
    path.lineWidth = 3;     //设置线宽

    //3.添加路径
    [path moveToPoint:CGPointMake(160, 100)];
    [path addLineToPoint:CGPointMake(100, 220)];
    [path addLineToPoint:CGPointMake(220, 220)];

    [path closePath];   //闭合路径(也可通过-addLineToPoint:方法添加)

    //4.渲染,完成绘制
    [path stroke];
    [path fill];
}

效果图:

画矩形

//矩形
- (void)drawRectPath {
    //1. 创建UIBezierPath对象并指定路径
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(60, 100, 200, 100)];

    //2. 配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色

    path.lineWidth = 3;     //设置线宽

    /*
        设置线条拐角样式
        typedef CF_ENUM(int32_t, CGLineCap) {
        kCGLineCapButt,     //默认
        kCGLineCapRound,    //圆角
        kCGLineCapSquare    //方形
        };
     */
    path.lineCapStyle = kCGLineCapRound;

    /*
        两条线连结点的样式
        typedef CF_ENUM(int32_t, CGLineJoin) {
        kCGLineJoinMiter,   //默认:斜接
        kCGLineJoinRound,   //圆滑衔接
        kCGLineJoinBevel    //圆滑衔接
        };
     */
    path.lineJoinStyle = kCGLineJoinBevel;  

    //3. 渲染,完成绘制
    [path stroke];
    [path fill];
}

效果图:

画椭圆(圆)

//椭圆
- (void)drawCiclePath {
    // 当传入参数为正方形时,绘制出的内切图形就是圆,为矩形时画出的就是椭圆
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(60, 100, 200,300)];

    //配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色

    path.lineWidth = 3;     //设置线宽

    //渲染
    [path stroke];
    [path fill];
}

效果图:
这里写图片描述

画带有圆角的矩形

- (void)drawRoundedRectPath {

    //创建带圆角的矩形  圆角半径:20
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(60, 100, 200, 200) cornerRadius:20];

    //创建可以指定圆角位置的矩形
    //第一个参数一样是传了个矩形
    //第二个参数是指定在哪个方向画圆角
    //第三个参数是一个CGSize类型,用来指定水平和垂直方向的半径的大小
    //UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(60, 100, 200, 200) byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(20, 20)];

    //配置属性
    [[UIColor yellowColor] setFill];    //设置填充颜色
    [[UIColor redColor] setStroke];     //设置描边颜色

    path.lineWidth = 3;     //设置线宽

    //渲染
    [path stroke];
    [path fill];
}

效果图:

指定圆角位置

画弧线

使用UIBeizerPath画弧线我们需要了解画弧线的参考系:

//画弧线
- (void)drawARCPath {
 //CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; 角度转弧度

    CGPoint center = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:DegreesToRadians(100) clockwise:YES];

    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 5.0;

    UIColor *strokeColor = [UIColor redColor];
    [strokeColor set];

    [path stroke];
}

我们要明确一点,画弧参数startAngle和endAngle使用的是弧度,而不是角度,因此我们需要将常用的角度转换成弧度。对于效果图中,我们设置弧的中心为控件的中心,起点弧度为0,也就是正东方向,而终点是135度角的位置。如果设置的clockwise:YES是逆时针方向绘制,如果设置为NO,效果如下:

画二次贝塞尔曲线

说到画二次贝塞尔曲线那就必须要说控制点了,首先我们看下面的图片:


画二次贝塞尔曲线我们用下面的方法实现:

- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

参数说明:

endPoint:终端点
controlPoint:控制点,对于二次贝塞尔曲线,只有一个控制点

- (void)drawSecondBezierPath {

    // 创建路径对象
    UIBezierPath *path = [UIBezierPath bezierPath];

    // 设置起始点,终点和控制点的位置
    CGPoint startPoint = CGPointMake(20, 200);
    CGPoint endPoint = CGPointMake(300, 200);
    CGPoint controlPoint = CGPointMake(100, 400);

    // 设置起始点位置
    [path moveToPoint:startPoint];

    // 添加二次曲线
    [path addQuadCurveToPoint:endPoint controlPoint:controlPoint];

    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 5.0;

    UIColor *strokeColor = [UIColor redColor];
    [strokeColor set];

    [path stroke];
}

效果图:

画三次贝塞尔曲线

贝塞尔曲线必定通过首尾两个点,称为端点;中间两个点虽然未必要通过,但却起到牵制曲线形状路径的作用,称作控制点。关于三次贝塞尔曲线的控制器,看下图:

如下方法就是画三次贝塞尔曲线的关键方法,以三个点画一段曲线,一般和-moveToPoint:配合使用。
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;

实现代码:

//画三次塞贝尔曲线
- (void)drawThirdBezierPath {
    UIBezierPath *path = [UIBezierPath bezierPath];

    // 设置起始端点
    [path moveToPoint:CGPointMake(20, 150)];

    [path addCurveToPoint:CGPointMake(300, 150)
            controlPoint1:CGPointMake(160, 0)
            controlPoint2:CGPointMake(160, 250)];

    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 5.0;

    UIColor *strokeColor = [UIColor redColor];
    [strokeColor set];

    [path stroke];
}

效果图:

我们可以通过两个控制点的坐标控制曲线的弯曲度,如果两个控制点的纵坐标和两个端点在同一水平线上,那么画出的就是一条直线了。

源代码在我的github网站(https://github.com/cokeduo/UIBezierPath-)有需要的小伙伴可以下载。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS使用公钥字符串进行RSA加密的步骤如下: 1. 将公钥字符串转换为NSData类型。 ``` NSString *publicKeyString = @"-----BEGIN PUBLIC KEY-----\n...公钥字符串...\n-----END PUBLIC KEY-----"; NSData *publicKeyData = [publicKeyString dataUsingEncoding:NSUTF8StringEncoding]; ``` 2. 创建SecKey对象。 ``` NSMutableDictionary *publicKeyAttributes = [[NSMutableDictionary alloc] init]; [publicKeyAttributes setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; [publicKeyAttributes setObject:@(2048) forKey:(__bridge id)kSecAttrKeySizeInBits]; [publicKeyAttributes setObject:publicKeyData forKey:(__bridge id)kSecValueData]; [publicKeyAttributes setObject:(__bridge id)kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass]; SecKeyRef publicKey; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKeyAttributes, (CFTypeRef *)&publicKey); ``` 3. 使用SecKey对象进行加密。 ``` NSData *plainData = [@"要加密的数据" dataUsingEncoding:NSUTF8StringEncoding]; size_t cipherBufferSize = SecKeyGetBlockSize(publicKey); uint8_t *cipherBuffer = malloc(cipherBufferSize); memset(cipherBuffer, 0, cipherBufferSize); OSStatus status = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, [plainData bytes], [plainData length], cipherBuffer, &cipherBufferSize); NSData *encryptedData = [NSData dataWithBytesNoCopy:cipherBuffer length:cipherBufferSize]; ``` 4. 释放SecKey对象。 ``` CFRelease(publicKey); ``` 注意:在iOS使用公钥加密时,需要使用PKCS#1填充模式(kSecPaddingPKCS1)。另外,如果公钥字符串中的换行符不是`\n`,需要将其替换为`\n`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值