UIGraphicsGetCurrentContext

作者: Carson_Zhu | 来源:发表于2018-02-07 02:35 被阅读674次

CGContextRef

CGContextRef即图形上下文。可以这么理解,我们绘图是需要一个载体或者说输出目标,它用来显示绘图信息,并且决定绘制的东西输出到哪个地方。可以形象的比喻context就像一个“画板”,我们得把图形绘制到这个画板上。所以,绘图必须要先有context

CGContextRef的获取

当你子类化了一个UIView并实现了自己的drawRect:方法后,一旦drawRect:方法被调用,Cocoa就会为你创建一个图形上下文,此时你对图形上下文的所有绘图操作都会显示在UIView上。

CGContextRef使用步骤
  • 先在drawRect方法中获得上下文context
  • 绘制图形(线,图形,图片等)
  • 设置一些修饰属性
  • 渲染到上下文,完成绘图
UIGraphics API介绍
  • 获取上下文
CGContextRef __nullable UIGraphicsGetCurrentContext(void)
  • 矩形填充
void UIRectFill(CGRect rect);

// 填充绘制使用指定的混合模式
void UIRectFillUsingBlendMode(CGRect rect, CGBlendMode blendMode);
  • 矩形描边
void UIRectFrame(CGRect rect);

// 描边绘制使用指定的混合模式
void UIRectFrameUsingBlendMode(CGRect rect, CGBlendMode blendMode);
  • 裁剪
void UIRectClip(CGRect rect);
CGContext API介绍
  • 线宽
void CGContextSetLineWidth(CGContextRef cg_nullable c, CGFloat width)
  • 终点类型
void CGContextSetLineCap(CGContextRef cg_nullable c, CGLineCap cap)
  • 交叉点类型
void CGContextSetLineJoin(CGContextRef cg_nullable c, CGLineJoin join)
  • 透明度
void CGContextSetAlpha(CGContextRef cg_nullable c, CGFloat alpha)
  • 透明矩形区域
void CGContextClearRect(CGContextRef cg_nullable c, CGRect rect)
  • 描边渲染
void CGContextStrokePath(CGContextRef cg_nullable c)
  • 描边颜色
void CGContextSetStrokeColor(CGContextRef cg_nullable c,
    const CGFloat * cg_nullable components)
  • 填充渲染
void CGContextFillPath(CGContextRef cg_nullable c)
  • 填充颜色
void CGContextSetFillColor(CGContextRef cg_nullable c,
    const CGFloat * cg_nullable components)
  • 裁剪
void CGContextClip(CGContextRef cg_nullable c)
  • 闭合路径
void CGContextClosePath(CGContextRef cg_nullable c)
  • 设置阴影
void CGContextSetShadowWithColor(CGContextRef cg_nullable c,
    CGSize offset, CGFloat blur, CGColorRef __nullable color)
  • 设置颜色渐变
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSArray* gradientColors = [NSArray arrayWithObjects:
                               (id)[UIColor whiteColor].CGColor,
                               (id)[UIColor blackColor].CGColor, nil];
CGFloat gradientLocations[] = {0, 1};

CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations);
CGPoint startCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
CGFloat radius = MAX(CGRectGetHeight(rect), CGRectGetWidth(rect));

CGContextDrawRadialGradient(context, gradient, startCenter, 0, startCenter, radius, 0);
  • 设置线性渐变
CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(200, 200);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
绘制
  • 画线
// 1.获取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();  
// 2.画线
CGContextMoveToPoint(contextRef, 20, 80); // 起点
CGContextAddLineToPoint(contextRef, self.frame.size.width-20, 80); //终点
// 3.修饰
CGContextSetRGBStrokeColor(contextRef, 0, 1.0, 0, 1.0); // 颜色
CGContextSetLineCap(contextRef, kCGLineCapRound); // 起点和重点圆角
CGContextSetLineJoin(contextRef, kCGLineJoinRound); // 转角圆角
// 4.渲染
CGContextStrokePath(contextRef);
  • 画矩形
/ 1.获取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();  
// 2.画矩形
CGContextAddRect(contextRef, CGRectMake(50, 50, 100, 100));
// 3.修饰
[[UIColor greenColor] set]; // 颜色
// 4.渲染
CGContextFillPath(contextRef);
  • 画圆
// 1.获取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();  
// 2.根据矩形画圆(椭圆只是设置不同的长宽)
CGContextAddEllipseInRect(contextRef, CGRectMake(10, 10, 50, 50));
// 3.修饰
[[UIColor greenColor] set]; // 颜色
// 4.渲染
CGContextFillPath(contextRef);
  • 画圆弧
// 1.获取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();  
// 2.画圆弧
/*
 * 参数一: 上下文
 * 参数二: 中心点x
 * 参数三: 中心点y
 * 参数四: 半径
 * 参数五: 开始弧度
 * 参数六: 结束弧度
 * 参数七: 0为顺时针,1为逆时针
 */
CGContextAddArc(contextRef, 200, 200, 50, M_PI, M_PI_4, 0);
// 3.修饰
[[UIColor greenColor] set]; // 颜色
// 4.渲染
CGContextFillPath(contextRef);
  • 绘制文字
- (void)drawRect:(CGRect)rect {
    //1.获取当前上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    //2.创建文字
    NSString *str = @"纸巾艺术";
    //设置字体样式
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    //NSFontAttributeName:字体大小
    dict[NSFontAttributeName] = [UIFont systemFontOfSize:25];
    //字体前景色
    dict[NSForegroundColorAttributeName] = [UIColor blueColor];
    //字体背景色
    dict[NSBackgroundColorAttributeName] = [UIColor redColor];
    //字体阴影
    NSShadow *shadow = [[NSShadow alloc]init];
    //阴影偏移量
    shadow.shadowOffset = CGSizeMake(2, 2);
    //阴影颜色
    shadow.shadowColor = [UIColor greenColor];
    //高斯模糊
    shadow.shadowBlurRadius = 5;
    dict[NSShadowAttributeName] = shadow;
    //字体间距
    dict[NSKernAttributeName] = @10;
    //绘制到上下文
    //从某一点开始绘制 默认 0 0点
    //    [str drawAtPoint:CGPointMake(100, 100) withAttributes:nil];
    //绘制区域设置
    [str drawInRect:rect withAttributes:dict];
    //添加到上下文
    CGContextStrokePath(contextRef);
}
  • 绘制图片
- (void)drawRect:(CGRect)rect {
    //1.获取当前的上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    //2.加载图片
    //我们这里只需要加载一次就够了,不需要多次加载,所以不应该保存这个缓存
    UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"222.png" ofType:nil]];
    //绘制一个多大的图片,并且设置他的混合模式以及透明度
    //Rect:大小位置
    //blendModel:混合模式
    //alpha:透明度
    [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1];
    //添加到上下文
    CGContextFillPath(contextRef);
}
重绘
  • 必须通过调用setNeedsDisplay或者setNeedsDisplayInRect:重绘。
  • 不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕,setNeedsLayout可以重新调用drawRect:方法,实现重绘的功能。
压栈
  • CGContextSaveGState
    压栈当前的绘制状态,当你在处理一个绘制context并且只是想保存的它的时候,CGContextSaveGState(context)将当前绘制状态压到一个context维护的绘制状态的栈中。

  • UIGraphicsPushContext
    压栈当前的绘制对象,生成新的绘制图层,当你需要在当前的context去创建一个新的CGContextRefUIGraphicsPushContext(context)context压到一个CGContextRefs(使得context成为current context)的栈中。

- (void)drawRect:(CGRect)rect {
    CGContextRef purple = UIGraphicsGetCurrentContext();
    // 设置紫色
    [[UIColor purpleColor] setStroke];
    // 设置线宽10
    CGContextSetLineWidth(purple, 10);
    // 画线
    CGContextMoveToPoint(purple, 50, 50);
    CGContextAddLineToPoint(purple, 50, 200);
    
    // 紫色CGContextRef保存到栈
    CGContextSaveGState(purple);
    
    // 重新设置颜色
    [[UIColor redColor] setStroke];
    // 重新设置线宽
    CGContextSetLineWidth(purple, 1);
    
    //把紫色的上下文从栈中取出来
    CGContextRestoreGState(purple);
    // 渲染
    CGContextStrokePath(purple);
}

CGContextSaveGState会保存上下文的信息,线宽、颜色、绘制信息等,取出上下文并使其恢复原样,重新设置并不会生效。

效果:紫色线,宽度10

- (void)drawRect:(CGRect)rect {
    CGContextRef purple = UIGraphicsGetCurrentContext();
    // 设置紫色
    [[UIColor purpleColor] setStroke];
    // 设置线宽10
    CGContextSetLineWidth(purple, 10);
    // 画线
    CGContextMoveToPoint(purple, 50, 50);
    CGContextAddLineToPoint(purple, 50, 200);
    
    // 紫色CGContextRef保存到栈
    UIGraphicsPushContext(purple);
    
    // 重新设置颜色
    [[UIColor redColor] setStroke];
    // 重新设置线宽
    CGContextSetLineWidth(purple, 1);
    
    //把紫色的上下文从栈中取出来
    UIGraphicsPopContext();
    // 渲染
    CGContextStrokePath(purple);
}

UIGraphicsPushContext会保存上下文的信息,线宽、颜色、绘制信息等,取出的是一个全新的绘图上下文,重新设置会生效。

效果:红色线,宽度1

相关文章

网友评论

    本文标题:UIGraphicsGetCurrentContext

    本文链接:https://www.haomeiwen.com/subject/wqznzxtx.html