第一種繪圖形式:在UIView的子類方法drawRect:中繪制一個藍色圓齿椅,使用UIKit在Cocoa為我們提供的當前上下文中完成繪圖任務(wù)。
- (void) drawRect: (CGRect) rect {
UIBezierPath* p = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,100,100)];
[[UIColor blueColor] setFill];
[p fill];
}
第二種繪圖形式:使用Core Graphics實現(xiàn)繪制藍色圓。
- (void) drawRect: (CGRect) rect {
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));
CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);
CGContextFillPath(con);
}
第三種繪圖方式:我將在UIView子類的drawLayer:inContext:方法中實現(xiàn)繪圖任務(wù)
drawLayer:inContext:方法是一個繪制圖層內(nèi)容的代理方法鲤妥。為了能夠調(diào)用
drawLayer:inContext:方法没酣,我們需要設(shè)定圖層的代理對象。但要注意徽级,不應(yīng)該將UIView對象設(shè)置為顯示層的委托對象,這是因為UIView對象已經(jīng)是隱式層的代理對象聊浅,
再將它設(shè)置為另一個層的委托對象就會出問題餐抢。輕量級的做法是編寫負責繪圖形的代理類。在MyView.h文件中聲明如下代碼:
@interface MyLayerDelegate : NSObject
@end
然后MyView.m文件中實現(xiàn)接口代碼:
@implementation MyLayerDelegate
- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx {
UIGraphicsPushContext(ctx);
UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];
[[UIColor blueColor] setFill];
[p fill];
UIGraphicsPopContext();
}
@end
直接將代理類的實現(xiàn)代碼放在MyView.m文件的#import代碼的下面低匙,這樣感覺好像在使用
私有類完成繪圖任務(wù)(雖然這不是私有類)旷痕。需要注意的是,我們需要將引用的上下文轉(zhuǎn)變成當前上下文顽冶。
因為圖層的代理是assign內(nèi)存管理策略欺抗,那么這里就不能以局部變量的形式創(chuàng)建MyLayerDelegate實例對象賦值給圖層代理。這里選擇在MyView.m中增加一個實例變量强重,因為實例變量默認是strong:
@interface MyView () {
MyLayerDelegate* _layerDeleagete;
}
@end
使用該圖層代理:
MyView *myView = [[MyView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
CALayer *myLayer = [CALayer layer];
_layerDelegate = [[MyLayerDelegate alloc] init];
myLayer.delegate = _layerDelegate;
[myView.layer addSublayer:myLayer];
[myView setNeedsDisplay]; // 調(diào)用此方法绞呈,drawLayer: inContext:方法才會被調(diào)用。
第四種繪圖形式:使用Core Graphics在drawLayer:inContext:方法中實現(xiàn)同樣操作间景,代碼如下:
- (void)drawLayer:(CALayer*)lay inContext:(CGContextRef)con {
CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));
CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);
CGContextFillPath(con);
}
最后报强,演示UIGraphicsBeginImageContextWithOptions的用法,并從上下文中生成一個UIImage對象拱燃。生成UIImage對象的代碼可以在任何地方被使用秉溉,它沒有上述繪圖方法那樣的限制。
第五種繪圖形式:使用UIKit實現(xiàn):
UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100), NO, 0);
UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];
[[UIColor blueColor] setFill];
[p fill];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
解釋一下UIGraphicsBeginImageContextWithOptions函數(shù)參數(shù)的含義:第一個參數(shù)表示所要創(chuàng)建的圖片的尺寸碗誉;第二個參數(shù)用來指定所生成圖片的背景是否為不透明召嘶,如上我們使用YES而不是NO,則我們得到的圖片背景將會是黑色,顯然這不是我想要的哮缺;第三個參數(shù)指定生成圖片的縮放因子弄跌,這個縮放因子與UIImage的scale屬性所指的含義是一致的。傳入0則表示讓圖片的縮放因子根據(jù)屏幕的分辨率而變化尝苇,所以我們得到的圖片不管是在單分辨率還是視網(wǎng)膜屏上看起來都會很好铛只。
第六種繪圖形式:使用Core Graphics實現(xiàn):
UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100), NO, 0);
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));
CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);
CGContextFillPath(con);
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage常用的繪圖操作
一個UIImage對象提供了向當前上下文繪制自身的方法埠胖。我們現(xiàn)在已經(jīng)知道如何獲取一個圖片類型的上下文并將它轉(zhuǎn)變當前上下文。
平移操作:下面的代碼展示了如何將UIImage繪制在當前的上下文中淳玩。
UIImage* mars = [UIImage imageNamed:@"Mars.png"];
CGSize sz = [mars size];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*2, sz.height), NO, 0);
[mars drawAtPoint:CGPointMake(0,0)];
[mars drawAtPoint:CGPointMake(sz.width,0)];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView* iv = [[UIImageView alloc] initWithImage:im];
[self.window.rootViewController.view addSubview: iv];
iv.center = self.window.center;
縮放操作:下面代碼展示了如何對UIImage進行縮放操作:
UIImage* mars = [UIImage imageNamed:@"Mars.png"];
CGSize sz = [mars size];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*2, sz.height*2), NO, 0);
[mars drawInRect:CGRectMake(0,0,sz.width*2,sz.height*2)];
[mars drawInRect:CGRectMake(sz.width/2.0, sz.height/2.0, sz.width, sz.height) blendMode:kCGBlendModeMultiply alpha:1.0];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
裁剪操作:下面代碼展示了如何獲取圖片的右半邊:
UIImage* mars = [UIImage imageNamed:@"Mars.png"];
CGSize sz = [mars size];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width/2.0, sz.height), NO, 0);
[mars drawAtPoint:CGPointMake(-sz.width/2.0, 0)];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();