Quartz 2D 请求上下文与强制重绘

本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看。

CGContextRef 

在调用drawRect:方法之前,视图对象会自动配置其描画环境,使代码可以立即进行描画。作为这些配置的一部分,UIView 对象会为当前绘制环境创建一个图形上下文,这个上下文就是CGContextRef 封装类型。

CGContextRef的对象是以栈的形式存放的,把对象放入栈中,使用CGContextSaveGState方法,将对象从栈中取出来,使用的是CGContextRestoreGState方法。

分析以下代码:

CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 将上下文压入栈中
    CGContextSaveGState(ctx);
    
    CGContextSetLineWidth(ctx, 10);
    CGContextSetLineCap(ctx, kCGLineCapRound);
    [[UIColor redColor] set];
    
    // 画线
    CGContextMoveToPoint(ctx, 50, 50);
    CGContextAddLineToPoint(ctx, 300, 450);
    CGContextStrokePath(ctx);
    
    CGContextRestoreGState(ctx);
    // 第二条线
    CGContextMoveToPoint(ctx, 30, 80);
    CGContextAddLineToPoint(ctx, 100, 350);
    CGContextStrokePath(ctx);
    
    CGContextRelease(ctx);

在绘制第二条线之前,先用CGContextRestoreGState方法获取到栈中的上下文对象,这个上下文对象是没有任何附加样式的。所以最终绘制出来的效果图如下:


限制上下文的绘制区域

默认情况下,上下文的绘制区域就是整个View所在的区域,不过我们也可以手动的规定绘制区域。可以使用CGContextClip进行绘制区域的裁切。示例代码如下:

CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    CGContextAddArc(ctx, 150, 150, 30, 0, M_PI*2, 1);
    // 裁切操作一定要放在绘制之前(裁切之后的操作,只能在裁切制定的区域进行相印的绘图操作了)
    CGContextClip(ctx);
    CGContextFillPath(ctx);
    
    UIImage *myImage = [UIImage imageNamed:@"www.jpg"];
    [myImage drawAtPoint:CGPointMake(110, 120)];
    
    CGContextRelease(ctx);

代码中,使用了CGContextClip(ctx); 所以绘制图片的区域只能在定义的圆形区域了,其他部分的任何绘制,都不会显示,最终效果图:



强制重绘: setNeedsDisplay

默认情况下,绘制工作只会在View第一次显示的时候调用,但可以通过[self setNeedsDisplay]进行手动的调用工作。

Demo:



当你拖动UISlider,上面的圆的半径也一直跟着变换。实现思路就是,UISlider的值在变化的时候,让上面的圆的半径也一直跟随着变化,并且一直在重绘。

UISlider的事件代码:

- (IBAction)drawArc:(UISlider *)sender {
    self.drawView.radius = sender.value;
}

DrawView中得主要代码:

-(void)setRadius:(CGFloat)radius {
    _radius = radius;
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    CGContextRef cxt = UIGraphicsGetCurrentContext();
    
    CGContextAddArc(cxt, 100, 100, self.radius, 0, M_PI*2, 1);
    
    CGContextStrokePath(cxt);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋恨雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值