很多时候,当你需要设计更高级的UI或者是减少设计师的工作量的时候,我们就需要用代码自行绘制UI,而自行绘制UI就需要用到CoreGraphics这个框架(OpenGL更高阶,目前还没达到这个水准)。
CGContext类,相当于Android里面的Canvas,使用UIGraphicsGetCurrentContext()获取当前CGContext的引用CGContextRef。我们在每一次的绘制之前都应该保存下原来的状态,待绘制完成后再恢复回原来的状态。所以CGContextSaveGState(ctx);… CGContextRestoreGState(ctx);都应该成对的出现,在他们之间的是绘制UI的代码。
CGPath类用于描述绘制的区域或者路线。在CGContext中addLine,addRect,其实都是在添加path,在添加完成path以后我们可以选择是fill该path,还是stroke该path。设置相应的颜色以及线宽即可。如果我们只需要在某个区域中绘制,我们可以在描述完path以后使用CGContextClip(ctx)来裁剪当前画布。
CGAffineTransform是一个仿射变换的结构体,相当于一个矩阵,用于进行二维平面的几何变换(平移,旋转,缩放),而且这些几何变换都已经有封装好的函数可调用,变换的顺序就是矩阵连乘的顺序,切不可把矩阵连乘的顺序放反,否则得到的结果可能不一样。
CGColorSpace类是用于界面颜色显示,通常颜色组成为RGBA(红,绿,蓝,透明度)四种,使用CGColorSpaceCreateDeviceRGB获取CGColorSpace的引用CGColorSpaceRef,需要注意的是,在CoreGraphics中,使用create方法生成的引用,最后都需要调用release方法释放掉,如CGColorSpaceCreateDeviceRGB()对应的就是CGColorSpaceRelease(rgb)。
转换代码
[UIImage imageWithGradientBeginColor:UIColorFromHex(0x626262) middleColor:UIColorFromHex(0x515151) endColor:UIColorFromHex(0x424242) size:CGSizeMake(320.0f, 44.0f)];
转换代码
+ (UIImage *)imageWithGradientBeginColor:(UIColor *)beginColor middleColor:(UIColor *)middleColor endColor:(UIColor *)endColor size:(CGSize)size
{
UIColor *colors[] = {beginColor, middleColor, endColor};
UIGraphicsBeginImageContext(size);
[[UIColor clearColor] setFill];
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
size_t numberOfComponents = CGColorGetNumberOfComponents(UIColorFromHex(0x111111).CGColor);
int numberOfColors = sizeof(colors)/sizeof(colors[0]);
CGFloat colorComponents[numberOfColors*numberOfComponents];
for (int i=0; i<numberOfColors; i++) {
UIColor *color = colors[i];
const CGFloat *components = CGColorGetComponents(color.CGColor);
for (int j=0; j<numberOfComponents; j++) {
colorComponents[i*numberOfComponents+j] = components[j];
}
}
CGFloat locations[] = {0.0f, 0.5f, 1.0f};
CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colorComponents, locations, sizeof(locations)/sizeof(locations[0]));
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextAddRect(ctx, CGRectMake(0.0f, 0.0f, size.width, size.height));
CGContextClip(ctx);
CGContextDrawLinearGradient(ctx, gradient, CGPointMake(size.width/2.0, 0.0f), CGPointMake(size.width/2.0, size.height), kCGGradientDrawsBeforeStartLocation|kCGGradientDrawsAfterEndLocation);
CGColorSpaceRelease(rgb);
CGGradientRelease(gradient);
CGAffineTransform myTextTransform;
CGContextSelectFont (ctx,
"Helvetica-Bold",
20.0,
kCGEncodingMacRoman);
CGContextSetCharacterSpacing (ctx, 2.0);
CGContextSetTextDrawingMode (ctx, kCGTextFill);
CGContextSetRGBFillColor(ctx, .8, .8, .8, .8);
// CGContextSetRGBStrokeColor (ctx, 0, 0, 1, 1);
myTextTransform = CGAffineTransformMakeScale(1.0, -1.0f);
CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation(140.0f, 30.0f));
CGContextSetTextMatrix (ctx, myTextTransform);// CGContextConcatCTM(ctx, CGAffineTransformConcat(myTextTransform, CGAffineTransformMakeTranslation(140.0f, 30.0f)));
CGContextShowTextAtPoint(ctx, 0.0f, 0.0f, "Title", 5);
CGContextRestoreGState(ctx);
UIImage *anImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// NSLog(@"%@", kCachePath);
// [UIImagePNGRepresentation(anImage) writeToFile:[kCachePath stringByAppendingPathComponent:@"linearGradient.png"] atomically:YES];
return anImage;
}
就记录这么多了,知晓了原理以后,总可以通过几何变换得到我们想要的图形,当然所有的形状都要能用数学的形势描述出来,这个需要很深的造诣。