core graphics

来源:互联网 发布:网络直播平台列表 编辑:程序博客网 时间:2024/05/01 07:50

可以在

UIView 

- drawRect:

Discussion

The default implementation of this method does nothing. Subclasses that use technologies such as Core Graphics and UIKit to draw their view’s content should override this method and implement their drawing code there. You do not need to override this method if your view sets its content in other ways. For example, you do not need to override this method if your view just displays a background color or if your view sets its content directly using the underlying layer object.

By the time this method is called, UIKit has configured the drawing environment appropriately for your view and you can simply call whatever drawing methods and functions you need to render your content. Specifically, UIKit creates and configures a graphics context for drawing and adjusts the transform of that context so that its origin matches the origin of your view’s bounds rectangle. You can get a reference to the graphics context using the UIGraphicsGetCurrentContext function, but do not establish a strong reference to the graphics context because it can change between calls to the drawRect: method.

Similarly, if you draw using OpenGL ES and the GLKView class, GLKit configures the underlying OpenGL ES context appropriately for your view before calling this method (or the glkView:drawInRect: method of your GLKView delegate), so you can simply issue whatever OpenGL ES commands you need to render your content. For more information about how to draw using OpenGL ES, see OpenGL ES Programming Guide for iOS

You should limit any drawing to the rectangle specified in the rect parameter. In addition, if the opaque property of your view is set to YES, your drawRect:method must totally fill the specified rectangle with opaque content. 

If you subclass UIView directly, your implementation of this method does not need to call super. However, if you are subclassing a different view class, you should call super at some point in your implementation. 

This method is called when a view is first displayed or when an event occurs that invalidates a visible part of the view. You should never call this method directly yourself. To invalidate part of your view, and thus cause that portion to be redrawn, call the setNeedsDisplay or setNeedsDisplayInRect: method instead.



layer

- drawLayer: inContext

Asks the delegate to draw the layer’s contents.

If you do not want to set the contents of the layer directly using the displayLayer: method, you can implement this method and use it to draw the contents of your layer. You might prefer this method in cases where the layer’s content is already dynamic and must be regenerated. 

The context may be clipped to protect valid layer content. Subclasses that wish to find the actual region to draw can call the CGContextGetClipBoundingBoxfunction.


- (void)drawInContext:(CGContextRef)ctx 


Draws the layer’s content using the specified graphics context.

The default implementation of this method does not doing any drawing itself. If the layer’s delegate implements the  drawLayer:inContext: method, that method is called to do the actual drawing.

Subclasses can override this method and use it to draw the layer’s content. When drawing, all coordinates should be specified in points in the logical coordinate space.


重写三个方法 来进行绘图 操作

drawRect 在视图第一次出现的时候会调用。或者调用  - setNeedsDisplay 方法的时候 调用


第二个方法,

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx


 需要 设置 

1.代理

2.setNeedsDisplay 方法 

才会 执行

    CALayer *layer = [CALayer layer];

    layer.bounds = CGRectMake(0, 200, UIScreenSize.width, 0.57*UIScreenSize.height);

    layer.backgroundColor = [UIColor clearColor].CGColor;

    layer.anchorPoint = CGPointMake(0, 0);

    layer.delegate = self;

    [layer setNeedsDisplay];

    [_bgImageView.layer addSublayer:layer];


第三个

- (void)drawInContext:(CGContextRef)ctx {


自定义layer的时候 会用到

自己定义一个layer类,继承于CALayer

!要调用 setNeedsDisplay 方法 该方法才会 执行 

    _cLayer = [circleLayerlayer];

    _cLayer.bounds =CGRectMake(0, 70, UIScreenSize.width, 0.57*UIScreenSize.height);

    _cLayer.backgroundColor = [UIColorclearColor].CGColor;

    _cLayer.anchorPoint =CGPointMake(0, 0);

//    _cLayer.delegate = self;

    [_cLayer setNeedsDisplay];

    [_bgImageView.layeraddSublayer:_cLayer];


=============================分割线=======================

再来说一下 绘图的方法:

1.在以上三个方法中

利用 CGContextRef 上下文 来绘制图形

1)获取上下文

    CGContextRef ctx = UIGraphicsGetCurrentContext();

2)绘图

    CGContextMoveToPoint(<#CGContextRef  _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>)

    CGContextAddArc(ctx, 100, 100, 50, M_PI, 0, 0);

等等方法 来绘制

或者使用

UIBezierPath 来绘制path

然后

    CGContextAddPath(ctx, bPath.CGPath);

又或者使用

CAShapeLayer 和 UIBezierPath 可以不在 drawRect 等方法里边 来绘图 (draw...是调用的core graphics库来绘图,占用的CPU的性能,Core Animation 调用GPU来渲染,性能更优)


    CAShapeLayer *pointL = [CAShapeLayerlayer];

    UIBezierPath *arcPath = [UIBezierPathbezierPathWithArcCenter:CGPointMake(-0.2427*UIScreenSize.width, 0.17634*UIScreenSize.width)radius:5 startAngle:0endAngle:2*M_PIclockwise:YES];

    pointL.fillColor = [UIColorwhiteColor].CGColor;

    

    pointL.path = arcPath.CGPath;

    [self addSublayer:pointL];



3)渲染

    CGContextStrokePath(ctx);


    CGContextFillPath(ctx);

==============================分割线=====================================
还存在一个 图形上下文栈

    CGContextSaveGState(ctx);  // 存一份  最纯正的上下文 到栈里边



    CGContextStrokePath(ctx);  // 从栈里边 取出 已经存放的上下文 然后继续做后续 处理,此上下文不受上边已经渲染的上下文影响


注意:  如果想从上下文栈里 取出多个 上下文,那个必须 存进去 相应数量的 上下文,否则 会出现 crash


目前理解浅显,未完待续。。。







 

0 0
原创粉丝点击