零基础iOS开发学习日记—控件篇—Quartz2D

开头

Quartz2D

实际用处

  • 绘图,类似给头像加个圆框
  • 艺术字
  • 绘制路线

绘图

  • C和OC都可以实现,也可以混合实现,下面只整理了oc的
//1.创建路径对象
UIBezierPath *path = [UIBezierPath bezierPath];
//2.通过路径对象拼接路径
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(200, 100)];
//3.渲染
[path stroke];
复制代码

drawRect

  1. 这个方法当中可以获取到正确的上下文,代码要写到这个方法里
  2. rect参数代表当前viewbounds
  3. 系统调用,当这个view第一次显示的时候会调用;当这个view进行重绘的时候会调用
  4. 类型刷新,调用某个需要重绘的view对象的setNeedsDisplay的方法,全部刷新;调用setNeedsDisplayInRect:(CGRect)rect,刷新指定区域
  5. 手动调用的时候获取不到正确的上下文

形状

  • 圆或者圆弧
//arccenter 圆心 radius 半径 startAngle 起始位置 endAngle 结束位置 clockwise 是否为顺时针
//0是三点钟方向,向下为正,顺时针到180度
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI clockwise:1];
[path stroke];
复制代码
  • 椭圆
//x,y,a,b轴
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 50, 200, 100)];
复制代码
  • 圆角矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 100, 100) cornerRadius:5];
复制代码
  • 矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 100, 100)];
复制代码
  • 饼状图
NSArray *array = @[@0.3, @0.1, @0.2, @0.4];
CGFloat start = 0;
CGFloat end = 0;
for (int i = 0; i < array.count; i++) {
    end = 2 * M_PI * [array[i] floatValue] + start;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:start endAngle:end clockwise:1];
    //扇形 往圆心连线
    [path addLineToPoint:CGPointMake(150, 150)];
    //随机颜色
    [[UIColor colorWithRed:((float)arc4random_uniform(256) / 255.0) green:((float)arc4random_uniform(256) / 255.0) blue:((float)arc4random_uniform(256) / 255.0) alpha:1.0] set];
    [path fill];
    //下一次的起点等于上一次的终点
    start = end;
}
复制代码
  • 柱状图
NSArray *array = @[@1, @0.5, @0.7, @0.3, @0.1, @0.6];
//计算rect
for (int i = 0; i < array.count; i++) {
    CGFloat w = 20;
    CGFloat h = [array[i] floatValue] * rect.size.height;
    CGFloat x = i * 2 * w;
    CGFloat y = rect.size.height - h;
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];
    [[UIColor colorWithRed:((float)arc4random_uniform(256) / 255.0) green:((float)arc4random_uniform(256) / 255.0) blue:((float)arc4random_uniform(256) / 255.0) alpha:1.0] set];
    [path fill];
}
复制代码
  • 进度
  • vc中
- (IBAction)progressChange:(UISlider *)sender {
    self.progressView.progressValue = sender.value;
    NSLog(@"%.2f", self.progressView.progressValue);
}
复制代码
  • view中
- (void)setProgressValue:(CGFloat)progressValue
{
    _progressValue = progressValue;
    //如果有最新的数据,就直接重绘
    [self setNeedsDisplay];
}
复制代码
- (void)drawRect:(CGRect)rect {
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:- M_PI_2 endAngle:2 * M_PI * self.progressValue - M_PI_2 clockwise:1];
    [path addLineToPoint:CGPointMake(150, 150)];
    [[UIColor redColor] set];
    [path fill];
}
复制代码

样式

//线宽
[path setLineWidth:30];
//连接处
[path setLineJoinStyle:kCGLineJoinRound];
//头尾
[path setLineCapStyle:kCGLineCapRound];
//颜色
[[UIColor greenColor] setStroke];
复制代码

渲染方式

UIBezierPath *path = [UIBezierPath new];
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(150, 50)];
//关闭路径,闭合
[path closePath];
[path setLineWidth:10];
[path setLineJoinStyle:kCGLineJoinRound];

//同时设置
[[UIColor redColor] set]; 

//即填充又描边同时打开
[[UIColor greenColor] setStroke];
[[UIColor redColor] setFill];

[path stroke];//描边
[path fill]; // 填充
复制代码
  • 奇偶填充
  • 被覆盖过奇数次的点填充,被覆盖过偶数次的点不填充
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 200, 100)];
[path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1];
path.usesEvenOddFillRule = YES; // 设置奇偶填充规则
[path fill];
复制代码
  • 非零环绕熟
  • 非零环绕数,默认填充规则 从左到右跨过 顺时针 +1 从右到左跨过 逆时针 -1 如果最后为0,那么不填充
//1.获取当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//2.拼接路径,把路径添加到上下文中
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1]; //顺时针
UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:0]; //逆时针
CGContextAddPath(ctx, path.CGPath);
CGContextAddPath(ctx, path1.CGPath);

CGContextDrawPath(ctx, kCGPathFill);
复制代码

图文上下栈

  • 保存样式
  • 找离着最近的备份样式,类似{}打括号对应
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//备份样式 - 默认样式
CGContextSaveGState(ctx);
//拼接路径 把路径添加到上下文
CGContextAddArc(ctx, 150, 150, 100, 0, 2 * M_PI, 1);
CGContextMoveToPoint(ctx, 0, 0);
CGContextAddLineToPoint(ctx, 300, 300);

CGContextSetLineWidth(ctx, 10);
//备份样式 - 线宽10
CGContextSaveGState(ctx);

[[UIColor redColor] set];
//备份样式 - 颜色红色
CGContextSaveGState(ctx);

CGContextMoveToPoint(ctx, 20, 20);
CGContextAddLineToPoint(ctx, 250, 20);

//恢复样式,找离着最近的备份样式,类似{}打括号对应
//恢复样式 - 颜色红色
CGContextRestoreGState(ctx);
//恢复样式 - 线宽10
CGContextRestoreGState(ctx);
//恢复样式 - 默认样式
CGContextRestoreGState(ctx);

CGContextStrokePath(ctx);
复制代码

绘制文字

NSString *str = @"test";
//绘制
//创建shadow
NSShadow *s = [NSShadow new];
s.shadowOffset = CGSizeMake(5, 0); //阴影偏移量
s.shadowBlurRadius = 2; // 模糊程度 越小越清晰
s.shadowColor = [UIColor blackColor];
//固定起始点 NSFontAttributeName等
// NSBackgroundColorAttributeName:[UIColor greenColor]
//NSUnderlineStyleAttributeName:@(5) 下划线粗细
[str drawAtPoint:CGPointMake(50, 50) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20], NSForegroundColorAttributeName:[UIColor redColor], NSShadowAttributeName:s}];
//固定区域,左上角
[str drawInRect:rect withAttributes:nil];
复制代码

绘制图片

//绘制图片 如果显示图片的大小比view大会进行部分显示
UIImage *image = [UIImage imageNamed:@"1"];
//从某个位置开始绘制
[image drawAtPoint:CGPointMake(50, 50)];
//绘制到某一个区域 拉伸 变形 全部显示
[image drawInRect:rect];
//平铺到某一个区域
[image drawAsPatternInRect:rect];
复制代码

剪裁图片

UIImage *image = [UIImage imageNamed:@"Gin_1"];
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//1.先画显示的区域
//CGContextAddArc(ctx, 150, 150, 100, 0, 2 * M_PI , 1);
CGContextAddRect(ctx, CGRectMake(0, 0, 150, 150));
CGContextAddRect(ctx, CGRectMake(150, 150, 150, 150));
//2.裁剪
CGContextClip(ctx);
[image drawInRect:rect];
复制代码

图形上下文

//开启图片类型的图形上下文
//第二个参数opaque 是否透明,一般都传no;第三个参数 scale 影响导出图片的分辨率,传手机屏幕的缩放因子/0就相当于传入[UIScreen mainScreen].scale
UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), NO, 0);
//UIGraphicsBeginImageContext(CGSizeMake(300, 300)); == 等价于 UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), NO, 1);
//获取当前的上下文(图片类型)
CGContextRef ctx = UIGraphicsGetCurrentContext();
//拼接路径,把路径添加到上下文
CGContextMoveToPoint(ctx, 50, 50);
CGContextAddLineToPoint(ctx, 100, 100);
CGContextStrokePath(ctx);
//通过图片类型的图形上下文获取图片对象,取图片对象
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

//关闭图片类型的图形上下文
UIGraphicsEndImageContext();
复制代码

保存到沙盒中

//获取doc路径
NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [docPath stringByAppendingPathComponent:@"test.png"];
NSLog(@"%@", filePath);
//1.把image对象转换成nsdata
NSData *data = UIImagePNGRepresentation(image);

//2.通过data的wirt to file写入到沙盒
[data writeToFile:filePath atomically:YES];
复制代码

保存图片到相册

  • info.plist添加
Privacy - Photo Library Additions Usage Description
复制代码
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //获取图片
    UIImage *image = [UIImage imageNamed:@"papa"];
    //1.开启图片类型的图形上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    //2.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //3.画裁剪图形
    CGContextAddArc(ctx, image.size.width * 0.5, image.size.height * 0.5, image.size.width * 0.5, 0, 2 * M_PI, 1);
    //4.裁剪
    CGContextClip(ctx);
    //5.渲染并取出
    [image drawAtPoint:CGPointZero];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    //6.关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    
    self.imageView.image = newImage;
    
    //保存到相册,完成的回调是固定的,参数contextInfo负责标记
    //UIImageWriteToSavedPhotosAlbum(newImage, NULL, NULL, NULL);
    UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image: didFinishSavingWithError: contextInfo:), @"1231231231");
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    NSLog(@"保存完成 - %@", contextInfo);
}
复制代码

带圆环的图片

//获取图片
UIImage *image = [UIImage imageNamed:@"papa"];
CGFloat margin = 20;
//计算上下文大小
CGSize ctxSize = CGSizeMake(image.size.width + 2 * margin, image.size.height + 2 * margin);
//1.开启图片类型的图形上下文
UIGraphicsBeginImageContextWithOptions(ctxSize, NO, 0);
//2.计算圆心
CGPoint arcCenter = CGPointMake(ctxSize.width * 0.5, ctxSize.height * 0.5);
//3.计算半径
CGFloat radius = (image.size.width + margin) * 0.5;
//4.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//5.画圆环
CGContextAddArc(ctx, arcCenter.x, arcCenter.y, radius, 0, 2 * M_PI, 1);
//6.设置宽度
CGContextSetLineWidth(ctx, margin);
//7.渲染圆环
CGContextStrokePath(ctx);
//8.画显示区域
CGContextAddArc(ctx, arcCenter.x, arcCenter.y, image.size.width * 0.5, 0, 2 * M_PI, 1);
//9.裁剪
CGContextClip(ctx);
//10.画图片
[image drawAtPoint:CGPointMake(margin, margin)];
image = UIGraphicsGetImageFromCurrentImageContext();

UIImageView *imageView = [[UIImageView alloc] init];
imageView.backgroundColor = [UIColor redColor];
imageView.image = image;
imageView.frame = CGRectMake(100, 100, image.size.width, image.size.height);
[self.view addSubview:imageView];
//关闭
UIGraphicsEndImageContext();
复制代码

添加水印

UIImage *image = [UIImage imageNamed:@"papa"];
//1.开启图片上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//画大图
[image drawAtPoint:CGPointZero];
//图片水印
UIImage *logo = [UIImage imageNamed:@"99"];
[logo drawAtPoint:CGPointMake(image.size.width * 0.7, image.size.height * 0.7)];
//2.文字
NSString *str = @"test";
//3.画文字水印
[str drawAtPoint:CGPointMake(20, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20]}];
//保存相册
image = UIGraphicsGetImageFromCurrentImageContext();
//    UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);
self.imageView.image = image;
//关闭图形上下文
UIGraphicsEndImageContext();
复制代码

屏幕截图

//开启图片类型上下文
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
//获取当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//截图 把view内容放到上下文 渲染
[self.view.layer renderInContext:ctx];
//取出图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//关闭
UIGraphicsEndImageContext();

//保存到相册
UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享