iOS繪畫的三種方式

第一種繪圖形式:在UIView的子類方法drawRect:中繪制一個藍色圓,使用UIKit在Cocoa為我們提供的當前上下文中完成繪圖任務。

- (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)繪圖任務

drawLayer:inContext:方法是一個繪制圖層內(nèi)容的代理方法。為了能夠調(diào)用

drawLayer:inContext:方法,我們需要設定圖層的代理對象。但要注意,不應該將UIView對象設置為顯示層的委托對象,這是因為UIView對象已經(jīng)是隱式層的代理對象,

再將它設置為另一個層的委托對象就會出問題。輕量級的做法是編寫負責繪圖形的代理類。在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代碼的下面,這樣感覺好像在使用

私有類完成繪圖任務(雖然這不是私有類)。需要注意的是,我們需要將引用的上下文轉(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();

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容