封装CoreGraphics的API简化绘图操作

简介:

封装CoreGraphics的API简化绘图操作

 

效果

 

说明

1. 将CoreGraphics的API接口抽象为对象,让绘图变得简单易懂

2. 简化常用的绘制操作

3. 源码长期更新

 

源码

https://github.com/YouXianMing/CGContextObject



//
//  CGContextObject.h
//  DrawRect
//
//  Created by YouXianMing on 15/7/2.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import "RGBColor.h"
#import "GradientColor.h"
@class CGContextObject;


typedef void(^CGContextObjectDrawBlock_t)(CGContextObject *contextObject);


@interface CGContextObject : NSObject

/**
 *  操作句柄
 */
@property (nonatomic)          CGContextRef   context;

/**
 *  线头样式
 */
@property (nonatomic)          CGLineCap      lineCap;

/**
 *  线条宽度
 */
@property (nonatomic)          CGFloat        lineWidth;

/**
 *  线条颜色
 */
@property (nonatomic, strong)  RGBColor      *strokeColor;

/**
 *  填充颜色
 */
@property (nonatomic, strong)  RGBColor      *fillColor;

/**
 *  由context进行初始化
 *
 *  @param context 绘制句柄
 *
 *  @return 绘制对象
 */
- (instancetype)initWithCGContext:(CGContextRef)context;

#pragma mark - 绘制操作流程
/**
 *  开始path
 */
- (void)beginPath;

/**
 *  关闭path
 */
- (void)closePath;

/**
 *  线条绘制
 */
- (void)strokePath;

/**
 *  填充绘制
 */
- (void)fillPath;

/**
 *  线条绘制 + 填充绘制
 */
- (void)strokeAndFillPath;

/**
 *  绘制线条用block (beginPath + closePath + 你绘制的代码 + strokePath)
 *
 *  @param block 绘制用block
 */
- (void)drawStrokeBlock:(CGContextObjectDrawBlock_t)block;

/**
 *  填充区域用block (beginPath + closePath + 你绘制的代码 + fillPath)
 *
 *  @param block 填充用block
 */
- (void)drawFillBlock:(CGContextObjectDrawBlock_t)block;

/**
 *  绘制加填充
 *
 *  @param block 绘制加填充用block
 */
- (void)drawStrokeAndFillBlock:(CGContextObjectDrawBlock_t)block;

/**
 *  绘制线条用block (beginPath + closePath + 你绘制的代码 + strokePath)
 *
 *  @param block     绘制用block
 *  @param closePath 是否关闭曲线
 */
- (void)drawStrokeBlock:(CGContextObjectDrawBlock_t)block closePath:(BOOL)closePath;

/**
 *  填充区域用block (beginPath + closePath + 你绘制的代码 + fillPath)
 *
 *  @param block     绘制用block
 *  @param closePath 是否关闭曲线
 */
- (void)drawFillBlock:(CGContextObjectDrawBlock_t)block closePath:(BOOL)closePath;

/**
 *  绘制加填充
 *
 *  @param block     绘制用block
 *  @param closePath 是否关闭曲线
 */
- (void)drawStrokeAndFillBlock:(CGContextObjectDrawBlock_t)block closePath:(BOOL)closePath;

#pragma mark - 绘制图片API

- (void)drawImage:(UIImage *)image atPoint:(CGPoint)point;
- (void)drawImage:(UIImage *)image atPoint:(CGPoint)point blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
- (void)drawImage:(UIImage *)image inRect:(CGRect)rect;
- (void)drawImage:(UIImage *)image inRect:(CGRect)rect blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
- (void)drawImage:(UIImage *)image asPatternInRect:(CGRect)rect;

#pragma mark - 保存操作

/**
 *  将当前设置存取到栈区中(入栈操作)
 */
- (void)saveStateToStack;

/**
 *  从栈区中取出之前保存的设置(出栈操作)
 */
- (void)restoreStateFromStack;

#pragma mark - 图形绘制API
/**
 *  移动到起始点
 *
 *  @param point 起始点
 */
- (void)moveToStartPoint:(CGPoint)point;

/**
 *  添加一个点(与上一个点直线相连)
 *
 *  @param point 点
 */
- (void)addLineToPoint:(CGPoint)point;

/**
 *  添加二次贝塞尔曲线
 *
 *  @param point    结束点
 *  @param pointOne 控制点1
 *  @param pointTwo 控制点2
 */
- (void)addCurveToPoint:(CGPoint)point controlPointOne:(CGPoint)pointOne controlPointTwo:(CGPoint)pointTwo;

/**
 *  添加一次贝塞尔曲线
 *
 *  @param point        结束点
 *  @param controlPoint 控制点
 */
- (void)addQuadCurveToPoint:(CGPoint)point controlPoint:(CGPoint)controlPoint;

/**
 *  在指定的区域填充彩色的矩形(此为直接绘制)
 *
 *  @param rect          指定的区域
 *  @param gradientColor 渐变色对象
 */
- (void)drawLinearGradientAtClipToRect:(CGRect)rect gradientColor:(GradientColor *)gradientColor;

#pragma mark - 
/**
 *  添加一个矩形
 *
 *  @param rect
 */
- (void)addRect:(CGRect)rect;

/**
 *  在给定的矩形中绘制椭圆
 *
 *  @param rect
 */
- (void)addEllipseInRect:(CGRect)rect;

/**
 *  将string绘制在指定的点上
 *
 *  @param string     字符串
 *  @param point      点
 *  @param attributes 富文本设置(可以为空)
 */
- (void)drawString:(NSString *)string atPoint:(CGPoint)point withAttributes:(NSDictionary *)attributes;

/**
 *  将string绘制在制定的区域
 *
 *  @param string     字符串
 *  @param rect       区域
 *  @param attributes 富文本设置(可以为空)
 */
- (void)drawString:(NSString *)string inRect:(CGRect)rect withAttributes:(NSDictionary *)attributes;

/**
 *  将富文本绘制在制定的点上
 *
 *  @param string 富文本
 *  @param point  点
 */
- (void)drawAttributedString:(NSAttributedString *)string atPoint:(CGPoint)point;

/**
 *  将富文本绘制在制定的矩形中
 *
 *  @param string 富文本
 *  @param rect   矩形
 */
- (void)drawAttributedString:(NSAttributedString *)string inRect:(CGRect)rect;

@end


//
//  CGContextObject.m
//  DrawRect
//
//  Created by YouXianMing on 15/7/2.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import "CGContextObject.h"

@interface CGContextObject ()

@end

@implementation CGContextObject

- (instancetype)initWithCGContext:(CGContextRef)context {
    
    self = [super init];
    if (self) {
        
        self.context = context;
    }
    
    return self;
}

- (void)moveToStartPoint:(CGPoint)point {
    
    if (_context) {
        CGContextMoveToPoint(_context, point.x, point.y);
    }
}

- (void)addLineToPoint:(CGPoint)point {
    
    if (_context) {
        CGContextAddLineToPoint(_context, point.x, point.y);
    }
}

- (void)addCurveToPoint:(CGPoint)point controlPointOne:(CGPoint)pointOne controlPointTwo:(CGPoint)pointTwo {

    if (_context) {
        CGContextAddCurveToPoint(_context, pointOne.x, pointOne.y, pointTwo.x, pointTwo.y, point.x, point.y);
    }
}

- (void)addQuadCurveToPoint:(CGPoint)point controlPoint:(CGPoint)controlPoint {
    
    if (_context) {
        CGContextAddQuadCurveToPoint(_context, controlPoint.x, controlPoint.y, point.x, point.y);
    }
}

- (void)drawLinearGradientAtClipToRect:(CGRect)rect gradientColor:(GradientColor *)gradientColor {
    
    [self saveStateToStack];
    
    
    if (_context) {
        
        CGContextClipToRect(_context, rect);
        
        CGContextDrawLinearGradient(_context,
                                    gradientColor.gradientRef,
                                    gradientColor.gradientStartPoint,
                                    gradientColor.gradientEndPoint, kCGGradientDrawsBeforeStartLocation);
    }
    
    
    [self restoreStateFromStack];
}

- (void)addRect:(CGRect)rect {

    if (_context) {
        CGContextAddRect(_context, rect);
    }
}

- (void)addEllipseInRect:(CGRect)rect {
    
    if (_context) {
        CGContextAddEllipseInRect(_context, rect);
    }
}

- (void)drawString:(NSString *)string atPoint:(CGPoint)point withAttributes:(NSDictionary *)attributes {

    [string drawAtPoint:point withAttributes:attributes];
}

- (void)drawString:(NSString *)string inRect:(CGRect)rect withAttributes:(NSDictionary *)attributes {

    [string drawInRect:rect withAttributes:attributes];
}

- (void)drawAttributedString:(NSAttributedString *)string atPoint:(CGPoint)point {

    [string drawAtPoint:point];
}

- (void)drawAttributedString:(NSAttributedString *)string inRect:(CGRect)rect {

    [string drawInRect:rect];
}

- (void)beginPath {
    
    if (_context) {
        CGContextBeginPath(_context);
    }
}

- (void)closePath {

    if (_context) {
        CGContextClosePath(_context);
    }
}

- (void)strokePath {

    if (_context) {
        CGContextStrokePath(_context);
    }
}

- (void)fillPath {

    if (_context) {
        CGContextFillPath(_context);
    }
}

- (void)strokeAndFillPath {

    if (_context) {
        CGContextDrawPath(_context, kCGPathFillStroke);
    }
}

- (void)drawStrokeBlock:(CGContextObjectDrawBlock_t)block {

    [self beginPath];
    
    __weak CGContextObject *weakSelf = self;
    
    block(weakSelf);
    
    [self closePath];
    
    [self strokePath];
}

- (void)drawFillBlock:(CGContextObjectDrawBlock_t)block {
    
    [self beginPath];
    
    __weak CGContextObject *weakSelf = self;
    
    block(weakSelf);
    
    [self closePath];
    
    [self fillPath];
}

- (void)drawStrokeAndFillBlock:(CGContextObjectDrawBlock_t)block {

    [self beginPath];
    
    __weak CGContextObject *weakSelf = self;
    
    block(weakSelf);
    
    [self closePath];
    
    [self strokeAndFillPath];
}

- (void)drawStrokeBlock:(CGContextObjectDrawBlock_t)block closePath:(BOOL)closePath {

    [self beginPath];
    
    __weak CGContextObject *weakSelf = self;
    
    block(weakSelf);
    
    if (closePath) {
        [self closePath];
    }
    
    [self strokePath];
}

- (void)drawFillBlock:(CGContextObjectDrawBlock_t)block closePath:(BOOL)closePath {

    [self beginPath];
    
    __weak CGContextObject *weakSelf = self;
    
    block(weakSelf);
    
    if (closePath) {
        [self closePath];
    }
    
    [self fillPath];
}

- (void)drawStrokeAndFillBlock:(CGContextObjectDrawBlock_t)block closePath:(BOOL)closePath {

    [self beginPath];
    
    __weak CGContextObject *weakSelf = self;
    
    block(weakSelf);
    
    if (closePath) {
        [self closePath];
    }
    
    [self strokeAndFillPath];
}

- (void)drawImage:(UIImage *)image atPoint:(CGPoint)point {

    [image drawAtPoint:point];
}

- (void)drawImage:(UIImage *)image atPoint:(CGPoint)point blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha {

    [image drawAtPoint:point blendMode:blendMode alpha:alpha];
}

- (void)drawImage:(UIImage *)image inRect:(CGRect)rect {

    [image drawInRect:rect];
}

- (void)drawImage:(UIImage *)image inRect:(CGRect)rect blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha {

    [image drawInRect:rect blendMode:blendMode alpha:alpha];
}

- (void)drawImage:(UIImage *)image asPatternInRect:(CGRect)rect {

    [image drawAsPatternInRect:rect];
}

- (void)saveStateToStack {
    
    if (_context) {
        CGContextSaveGState(_context);
    }
}

- (void)restoreStateFromStack {
    
    if (_context) {
        CGContextRestoreGState(_context);
    }
}

#pragma mark - 重写setter,getter方法
@synthesize strokeColor = _strokeColor;
- (void)setStrokeColor:(RGBColor *)strokeColor {

    if (_context) {
        
        _strokeColor = strokeColor;
        CGContextSetRGBStrokeColor(_context, strokeColor.red, strokeColor.green, strokeColor.blue, strokeColor.alpha);
    }
}
- (RGBColor *)strokeColor {

    return _strokeColor;
}

@synthesize fillColor = _fillColor;
- (void)setFillColor:(RGBColor *)fillColor {
    
    if (_context) {
        
        _fillColor = fillColor;
        CGContextSetRGBFillColor(_context, fillColor.red, fillColor.green, fillColor.blue, fillColor.alpha);
    }
}
- (RGBColor *)fillColor {
    
    return _fillColor;
}

@synthesize lineWidth = _lineWidth;
- (void)setLineWidth:(CGFloat)lineWidth {
    
    if (_context) {
        
        _lineWidth = lineWidth;
        CGContextSetLineWidth(_context, lineWidth);
    }
}
- (CGFloat)lineWidth {
    
    return _lineWidth;
}

@synthesize lineCap = _lineCap;
- (void)setLineCap:(CGLineCap)lineCap {
    
    if (_context) {
    
        _lineCap = lineCap;
        CGContextSetLineCap(_context, lineCap);
    }
    
}
- (CGLineCap)lineCap {

    return _lineCap;
}

@end

细节

目录
相关文章
|
9天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。
|
27天前
|
Java API Maven
HDFS的API操作
HDFS的API操作
25 0
|
2月前
|
API
Poi 中文API文档 「40种操作 Excel文件的姿势」
Poi 中文API文档 「40种操作 Excel文件的姿势」
116 0
|
3月前
|
JavaScript API
【vue实战项目】通用管理系统:api封装、404页
【vue实战项目】通用管理系统:api封装、404页
37 3
|
3月前
|
JSON API 数据格式
在钉钉开放平台中,创建或更新OA审批表单模板需要通过API接口进行操作
在钉钉开放平台中,创建或更新OA审批表单模板需要通过API接口进行操作【1月更文挑战第20天】【1月更文挑战第97篇】
46 1
|
4月前
|
Java API
java 操作es api
java 操作es api
42 0
|
4月前
|
安全 大数据 API
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
62 0
|
30天前
|
前端开发 API 数据处理
uni-app 封装api请求
uni-app 封装api请求
13 0
|
2月前
|
缓存 监控 测试技术
ERP系统对接方案与API接口封装系列(高并发)
企业资源规划(ERP)系统是现代企业管理的核心,它集成了企业内部的各个部门和业务流程。为了实现ERP系统与其他外部系统或应用程序之间的数据交换和协作,需要对接方案。API(应用程序编程接口)是实现系统对接的常用方法之一。
|
3月前
|
前端开发 JavaScript 小程序
【uniapp】十分钟带你封装uniapp的api请求
【uniapp】十分钟带你封装uniapp的api请求
112 0

热门文章

最新文章