執行方法時,系統會自行創建畫布(CGContext),並且講畫布推到堆棧的棧頂位置
執行完畢後,系統會執行pop出這個畫布。
- (void)drawRect:(CGRect)rect{
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));
CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);
CGContextFillPath(con);
}
UIGraphicsBeginImageContextWithOptions (
CGSize size,
BOOL opaque,
CGFloat scale
);
參數:size–畫布大小
參數:opaque–不透明
參數:scale–放大比例,設置為0,表示和屏幕自適應。(此參數和image中的scale是一樣的)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100), NO, 0);
UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];
[[UIColor blueColor] setFill];
[p fill];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc]initWithImage:im];
imgView.frame = CGRectMake(100, 100, im.size.width, im.size.height);
[self.view addSubview:imgView];
UIView子類的drawLayer:inContext:方法中實現繪圖任務。drawLayer:inContext:方法是一個繪制圖層內容的代理方法。為了能夠調用drawLayer:inContext:方法,我們需要設定圖層的代理對象。
注意點:
1. drawLayer:inContext:代理方法需要寫在UIView子類中,如果寫在UIViewController中會出現內存過度釋放問題。
2. 不應該將UIView對象設置為顯示層的委托對象,這是因為UIView對象已經是隱式層的代理對象,再將它設置為另一個層的委托對象就會出問題。
下面是實現代碼的聲明和實現文件
@interface LayerDelegate : NSObject
@end
@interface LayerDelegateView : UIView
@end
@implementation LayerDelegate
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
//1.繪制圖形
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(50, 50, 100, 100));
//設置屬性(顏色)
CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
//2.渲染
CGContextFillPath(ctx);
}
@end
@interface LayerDelegateView ()
@property (strong, nonatomic) LayerDelegate *delegate;
@end
@implementation LayerDelegateView
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
CALayer *myLayer = [CALayer layer];
self.delegate = [[LayerDelegate alloc]init];
myLayer.delegate = self.delegate;
myLayer.backgroundColor = [UIColor brownColor].CGColor;
myLayer.bounds = CGRectMake(0, 0, 200, 150);
myLayer.anchorPoint = CGPointZero;
myLayer.position = CGPointMake(100, 100);
myLayer.cornerRadius = 20;
myLayer.shadowColor = [UIColor blackColor].CGColor;
myLayer.shadowOffset = CGSizeMake(10, 20);
myLayer.shadowOpacity = 0.6;
[myLayer setNeedsDisplay]; // 調用此方法,drawLayer: inContext:方法才會被調用。
[self.layer addSublayer:myLayer];
}
return self;
}
@end
CGContext被存放在系統的一個繪圖上下文堆棧區中,我們編輯CGContext的時候,可以將CGContext push到棧頂,然後在編輯完成時,將GContext pop出棧頂。下面的代碼簡單介紹了其使用。
UIImage *img1;
UIImage *img2;
//在繪圖上下文1中繪圖
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0);
[@第一個 drawInRect:CGRectMake(10, 20, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12]}];
img1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsPushContext(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();//!!!: 這個等等刪掉試試看
//跳轉到繪圖上下文2中繪圖
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0);
[@第二個 drawInRect:CGRectMake(10, 20, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12]}];
img2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//pop返回到繪圖上下文1中繪圖
UIGraphicsPopContext();
[@再第一個 drawInRect:CGRectMake(110, 20, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12]}];
img1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsPushContext(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
//pop返回到繪圖上下文1中繪圖
UIGraphicsPopContext();
[@再再第一個 drawInRect:CGRectMake(10, 40, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12]}];
img1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//繪圖上下文1和繪畫上下文2中的圖片顯示出來
UIImageView *imgView1 = [[UIImageView alloc]initWithImage:img1];
imgView1.frame = CGRectMake(0, 100, 200, 100);
imgView1.backgroundColor = [UIColor yellowColor];
[self.view addSubview:imgView1];
UIImageView *imgView2 = [[UIImageView alloc]initWithImage:img2];
imgView2.frame = CGRectMake(0, 300, 200, 100);
imgView2.backgroundColor = [UIColor redColor];
[self.view addSubview:imgView2];