關於顏色梯度漸變視圖的建立,CoreGraphics框架中提供了兩個類型CGShadingRef與CGGradientRef。CoreGraphics框架在繪製梯度漸變時,有兩種繪製方式,分別爲軸向繪製與徑向繪製。軸向繪製是指肯定兩個點,起點與終點鏈接的直線做爲梯度漸變的軸,垂直於此軸的線共享相同的顏色,由起點向終點進行顏色漸變。徑向漸變是指由兩個圓鏈接成圓臺,在同一圓周上的全部點共享相同的顏色,由起始圓向終點圓進行顏色漸變。數組
軸向漸變:框架
徑向漸變:函數
前面說到,CGShadingRef與CGGradientRef均可以用於建立梯度漸變視圖,這兩個類型在使用使又有一些不一樣,CGShadingRef在使用使須要開發者爲其提供一個顏色計算方法,CGGradientRef則不須要,相比之下,CGGradientRef更像是爲了方便開發者使用而從CGShadingRef中擴展出的一個類型。測試
建立一個UIView子類,在其drawRect:方法中編寫以下測試代碼:ui
-(void)drawRect:(CGRect)rect{ CGGradientRef gradientRef; CGColorSpaceRef colorSpaceRef; CGFloat locs[2] = {0,1}; CGFloat colors[8] = { 1.0, 0, 0, 1.0, // 前4個爲起始顏色的rgba 0, 1, 0, 1.0 }; // 後4個爲結束顏色的rgba colorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gradientRef = CGGradientCreateWithColorComponents (colorSpaceRef, colors, locs, 2); CGContextRef contextRef = UIGraphicsGetCurrentContext(); //這個方法用於建立軸向漸變 // CGContextDrawLinearGradient(contextRef, gradientRef, rect.origin, CGPointMake(rect.origin.x+rect.size.width, rect.origin.y+rect.size.height), 0); //這個方法用於建立徑向漸變 CGContextDrawRadialGradient(contextRef, gradientRef, CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2), rect.size.width/2, CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2), rect.size.width/4, 0); }
CGContextDrawRadiaGradient()方法中的參數解析以下:spa
/* c:繪圖上下文 gradieent:漸變對象 startCenter:漸變起始圓心 startRadius:漸變起始圓半徑 endCenter:漸變終止圓心 endRadius:漸變終止圓半徑 options:漸變的填充風格 設置爲0則不進行填充 typedef CF_OPTIONS (uint32_t, CGGradientDrawingOptions) { kCGGradientDrawsBeforeStartLocation = (1 << 0), //起點之前也進行填充 kCGGradientDrawsAfterEndLocation = (1 << 1) //終點以後也進行填充 }; */ CG_EXTERN void CGContextDrawRadialGradient(CGContextRef cg_nullable c, CGGradientRef cg_nullable gradient, CGPoint startCenter, CGFloat startRadius, CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions options) CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
CGGradient中定義的方法解析以下:指針
//獲取CGGradient類在CoreGraphics框架中的id CFTypeID CGGradientGetTypeID(void); //建立CGGradientRef /* space:色彩空間 components:色值數組 locations:漸變臨界點 count:locations數組中元素個數 */ CGGradientRef __nullable CGGradientCreateWithColorComponents( CGColorSpaceRef cg_nullable space, const CGFloat * cg_nullable components, const CGFloat * __nullable locations, size_t count); //建立CGGradientRef 這個方法locations中的元素個數須要與colors中的對應 /* space:色彩空間 colors:顏色數組 locations:漸變臨界點 */ CGGradientRef __nullable CGGradientCreateWithColors( CGColorSpaceRef __nullable space, CFArrayRef cg_nullable colors, const CGFloat * __nullable locations); //進行引用計數+1 CGGradientRef cg_nullable CGGradientRetain( CGGradientRef cg_nullable gradient); //進行引用計數-1 void CGGradientRelease(CGGradientRef cg_nullable gradient);
CGShadingRef的使用就不像CGGradientRef那麼方便,其中方法解析以下:code
//獲取CGShadingRef在CoreGraphics框架中的id CFTypeID CGShadingGetTypeID(void); //建立軸向漸變的CGShadingRef對象 /* space:色彩空間 start:起始點 end:結束點 function:顏色計算函數 extendStart:是否填充起始點之前 extendEnd:是否填充結束點以後 */ CGShadingRef __nullable CGShadingCreateAxial( CGColorSpaceRef cg_nullable space, CGPoint start, CGPoint end, CGFunctionRef cg_nullable function, bool extendStart, bool extendEnd); //建立徑向漸變的CGShadingRef對象 參數同上 CGShadingRef __nullable CGShadingCreateRadial( CGColorSpaceRef cg_nullable space, CGPoint start, CGFloat startRadius, CGPoint end, CGFloat endRadius, CGFunctionRef cg_nullable function, bool extendStart, bool extendEnd); //引用計數+1 CGShadingRef cg_nullable CGShadingRetain(CGShadingRef cg_nullable shading); //引用計數-1 void CGShadingRelease(CGShadingRef cg_nullable shading);
示例代碼以下:component
//顏色計算函數 /* info 是開發者後面將傳入的色彩空間的參數個數 in 爲輸入參數 對應0-1之間 out 爲輸出參數 爲所對應顏色空間的每一個色值 */ static void myCalculateShadingValues (void *info, const CGFloat *in, CGFloat *out) { size_t k, components; double frequency[4] = { 55, 220, 110, 0 }; //獲取色彩空間的色值數 components = (size_t)info; for (k = 0; k < components - 1; k++) //*out++ 的做用是指針右移 out指針能夠理解爲數組 右移做用和數組賦值一致 *out++ = (1 + sin(*in * frequency[k]))/2; //最後追加上透明度值 *out++ = 1; // alpha } -(void)drawRect:(CGRect)rect{ size_t numComponents; //輸入參數的範圍 其中元素個數是 輸入參數個數的兩倍 static const CGFloat input_value_range [2] = { 0, 1 }; //輸出參數的範圍 其中元素個數是 輸出參數個數的兩倍 static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; //組合回調函數 static const CGFunctionCallbacks callbacks = { 0, &myCalculateShadingValues, NULL }; //獲取色彩空間的色值數 numComponents = 1 + CGColorSpaceGetNumberOfComponents (CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); //建立CGFunctionRef CGFunctionRef func = CGFunctionCreate ((void *) numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks); CGPoint startPoint, endPoint; CGFloat startRadius, endRadius; CGAffineTransform myTransform; //起始圓位置 startPoint = CGPointMake(0.25,0.3); //半徑 startRadius = .1; //終止圓位置 endPoint = CGPointMake(.7,0.7); //半徑 endRadius = .25; //建立CGShadingRef CGShadingRef myShading = CGShadingCreateRadial (CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), startPoint, startRadius, endPoint, endRadius, func, false, false); CGContextRef context = UIGraphicsGetCurrentContext(); //進行transform的映射 myTransform = CGAffineTransformMakeScale(320, 568); CGContextConcatCTM(context, myTransform); CGContextSaveGState(context); //進行繪製 CGContextDrawShading(context, myShading); }
上面的示例代碼效果以下圖:orm
靈活的應用CGContextDrawRadialGradient()方法能夠建立出僞立體效果的圖形,例如以下代碼:
-(void)drawRect:(CGRect)rect{ CGGradientRef gradientRef; CGColorSpaceRef colorSpaceRef; CGFloat locs[2] = {0,1}; CGFloat colors[8] = { 1.0, 0, 0, 1.0, // 前4個爲起始顏色的rgba 1, 1, 1, 1.0 }; // 後4個爲結束顏色的rgba colorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gradientRef = CGGradientCreateWithColorComponents (colorSpaceRef, colors, locs, 2); CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGContextDrawRadialGradient(contextRef, gradientRef, CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2), rect.size.width/2, CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2-100), 0, 0); }
經過調整內圓的位置和半徑,能夠作到光影的移動,效果以下:
//模擬金屬原子 -(void)drawRect:(CGRect)rect{ CGGradientRef gradientRef; CGColorSpaceRef colorSpaceRef; CGFloat locs[8] = {0,0.2,0.4,0.5,0.6,0.8,0.9,1.0}; CGFloat colors[64] = { 1.0, 0, 0, 1.0, // 前4個爲起始顏色的rgba 0.0, 1, 0, 1.0, 0.0, 0, 1, 1.0, 1.0, 0, 0, 1.0, 0.0, 1, 0, 1.0, 1.0, 0, 0, 1.0, 1.0, 1, 0, 1.0, 1, 1, 1, 1.0 }; // 後4個爲結束顏色的rgba colorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gradientRef = CGGradientCreateWithColorComponents (colorSpaceRef, colors, locs, 8); CGContextRef contextRef = UIGraphicsGetCurrentContext(); // CGContextDrawLinearGradient(contextRef, gradientRef, rect.origin, CGPointMake(rect.origin.x+rect.size.width, rect.origin.y+rect.size.height), 0); CGContextDrawRadialGradient(contextRef, gradientRef, CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2), rect.size.width/2, CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2-100), 0, 0); }
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592