iOS開發CoreGraphics核心圖形框架之五——Patterns模型的應用

iOS開發CoreGraphics核心圖形框架之五——Patterns模型的應用

1、引言

    Patterns稱爲模型可能並不直觀,說一個場景咱們或許就能夠更加容易的理解Patterns。在開發中,開發者常常會遇到這樣的需求,將某個圖片或者某個圖形進行平鋪做爲界面的背景,固然iOS中有現成的方法來將圖片轉換爲背景色進行背景的渲染,可是這種方式並不太靈活,例如背景花紋的着色,背景圖片的平鋪間距設置等需求都沒法知足。Patterns就是用來處理這樣的需求。數組

    Patterns能夠理解爲一個模型單元,即花紋背景中的一個花紋單元,開發者能夠自定義這個單元的繪製內容,一旦建立了CGPatternRef引用,開發者就能夠將它向普通顏色同樣進行使用,能夠進行填充,能夠進行路徑繪製等。框架

2、建立CGPatternRef模型引用

    在UIView子類的drawRect:方法中來作以下的測試:函數

- (void)drawRect:(CGRect)rect {
    // Drawing code
    //建立回調結構體 後面會介紹
    CGPatternCallbacks callback = {0,&drawPatternCallback,&releaseInfoCallback};
    //建立模型引用
    CGPatternRef pattren = CGPatternCreate(NULL, CGRectMake(0, 0, 30,30), CGAffineTransformIdentity, 35, 35, kCGPatternTilingConstantSpacing, false, &callback);
    //建立顏色數組 表明RGBA的值
    static const CGFloat color[4] = { 0, 1, 0, 1 };
    //建立顏色空間
    CGColorSpaceRef baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern (baseSpace);
    //設置填充顏色空間
    CGContextSetFillColorSpace (UIGraphicsGetCurrentContext(), patternSpace);
    //設置填充模型
    CGContextSetFillPattern(UIGraphicsGetCurrentContext(), pattren, color);
    //進行填充
    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, 200, 200));
    
}

上面的示例代碼中,有幾個地方須要進行介紹:測試

CGPatternCallBacks是CoreGraphics框架的CGPattern.h文件中定義的一個結構體,這個結構體組合了模型Pattern的版本,建立回調和釋放回調。建立回調和釋放回調須要傳入兩個方法塊的地址,即block。這兩個block的格式定義以下:spa

//建立模型回調的格式定義
//info參數爲須要傳遞給回調函數的數據
//content參數爲所繪製的圖形上下文
typedef void (*CGPatternDrawPatternCallback)(void * __nullable info,
                                             CGContextRef cg_nullable context);
//釋放回調 開發者能夠在其中進行內存的釋放
typedef void (*CGPatternReleaseInfoCallback)(void * __nullable info);

咱們所實現的drawPatternCallback(),releaseInfoCallback()方法示例以下:指針

// 繪製 回調
#define PSIZE 16
void drawPatternCallback(void *info,CGContextRef myContext){
//這裏我借用了官方文檔中的代碼 以下的代碼將繪製出五角星
    int k;
    double r, theta;
    
    r = 0.8 * PSIZE / 2;
    theta = 2 * M_PI * (2.0 / 5.0); // 144 degrees
    
    CGContextTranslateCTM (myContext, PSIZE/2, PSIZE/2);
    
    CGContextMoveToPoint(myContext, 0, r);
    for (k = 1; k < 5; k++) {
        CGContextAddLineToPoint (myContext,
                                 r * sin(k * theta),
                                 r * cos(k * theta));
    }
    CGContextClosePath(myContext);
    CGContextFillPath(myContext);
}


// 移除 回調
void releaseInfoCallback(void *info) {
   
}

在回過來看建立CGPatternRef的方法:code

/*
這個方法
第1個參數爲要傳遞進建立模型方法的信息
第2個參數爲設置每一個模型單元的尺寸
第3個參數設置模型的幾何變換
第4個參數設置模型的總體寬度  經過這個參數能夠設置邊距
第5個參數設置模型的總體高度  經過這個參數能夠設置邊距
第6個參數設置模型的渲染方式
第7個參數設置爲有色渲染仍是無色渲染 
第8個參數設置相關回調結構體
*/
CGPatternRef pattren = CGPatternCreate(NULL, CGRectMake(0, 0, 30,30), CGAffineTransformIdentity, 35, 35, kCGPatternTilingConstantSpacing, false, &callback);

關於模型的渲染方式,須要設置爲CGPatternTiling類型的枚舉,以下:orm

typedef CF_ENUM (int32_t, CGPatternTiling) {
    //無失真的平鋪 將調整單元之間的間距
    kCGPatternTilingNoDistortion,
    //細微調整單元大小
    kCGPatternTilingConstantSpacingMinimalDistortion,
    //恆定間距,經過調整單元大小實現 會失真
    kCGPatternTilingConstantSpacing
};

CGContextSetFillPattern()方法用於將模型設置爲要渲染界面的顏料,以後調用CGContextStrokePath(), CGContextFillPath(), CGContextFillRect()等相關方法均可以實現將模型鋪平渲染到指定容器。須要注意,CGContextSetFillPattern()方法中第1個參數爲繪圖上下文,第2個參數爲模型CGPatternRef引用,第3個參數爲一個色值數組,這裏若是模式是無色渲染方式建立的,須要傳入4個元素的RGBA數組,若是是有色模式建立的,須要傳入一個透明度值,能夠是float類型的指針。圖片

運行工程,效果以下圖所示:內存

將代碼簡單修改以下,就能夠實現以五角星圍成的矩形:

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGPatternCallbacks callback = {0,&drawPatternCallback,&releaseInfoCallback};
    CGPatternRef pattren = CGPatternCreate(NULL, CGRectMake(0, 0, 30,30), CGAffineTransformIdentity, 30, 30, kCGPatternTilingConstantSpacing, false, &callback);
    static const CGFloat color[4] = { 1, 0, 0, 1 };
    CGColorSpaceRef baseSpace;
    CGColorSpaceRef patternSpace;
    baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
    patternSpace = CGColorSpaceCreatePattern (baseSpace);
    CGContextSetStrokeColorSpace (UIGraphicsGetCurrentContext(), patternSpace);
    CGContextSetStrokePattern(UIGraphicsGetCurrentContext(), pattren, color);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 40);
    CGContextStrokeRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, 200, 200));
}

效果以下:

3、CGPattern中其餘方法

//獲取CGPattern在CoreGraphics框架中的id
CFTypeID CGPatternGetTypeID(void);
//進行引用計數加1
CGPatternRef cg_nullable CGPatternRetain(CGPatternRef cg_nullable pattern);
//進行引用計數減1
void CGPatternRelease(CGPatternRef cg_nullable pattern);

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索