A.关于Quiartz2D的一些细节
1.UIKit的工具已经封装了上下文引用,所以不用手动获取和渲染
1 - (void)drawRect:(CGRect)rect { 2 [[UIColor redColor] set]; 3 UIRectFill(CGRectMake(0, 0, 100, 100)); 4 }
2.多个path
1 - (void)drawRect:(CGRect)rect { 2 CGContextRef ctx = UIGraphicsGetCurrentContext(); 3 4 // 1.1创建第一个path 5 CGMutablePathRef linePath = CGPathCreateMutable(); 6 7 // 1.2.描绘path 8 CGPathMoveToPoint(linePath, NULL, 0, 0); 9 CGPathAddLineToPoint(linePath, NULL, 100, 100); 10 11 // 1.3.添加linePath到上下文 12 CGContextAddPath(ctx, linePath); 13 14 // 2添加一个圆的path 15 CGMutablePathRef circlePath = CGPathCreateMutable(); 16 CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(0, 0, 50, 50)); 17 CGContextAddPath(ctx, circlePath); 18 19 // 渲染上下文 20 CGContextStrokePath(ctx); 21 22 // 释放path 23 CGPathRelease(linePath); 24 CGPathRelease(circlePath); 25 }
B.自定义一个类似UIImageView的控件
1 // 2 // MyImageView.h 3 // MyImageView 4 // 5 // Created by hellovoidworld on 14/12/31. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @interface MyImageView : UIView 12 13 @property(nonatomic, weak) UIImage *image; 14 15 @end
1 // 2 // MyImageView.m 3 // MyImageView 4 // 5 // Created by hellovoidworld on 14/12/31. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "MyImageView.h" 10 11 @implementation MyImageView 12 13 - (void)setImage:(UIImage *)image { 14 _image = image; 15 16 // 重新设置了图片的时候,重绘 17 [self setNeedsDisplay]; 18 } 19 20 - (void)drawRect:(CGRect)rect { 21 [self.image drawInRect:rect]; 22 } 23 24 @end 25 26 controller: 27 - (void)viewDidLoad { 28 [super viewDidLoad]; 29 // Do any additional setup after loading the view, typically from a nib. 30 31 MyImageView *imageView = [[MyImageView alloc] init]; 32 imageView.frame = CGRectMake(0, 0, 200, 320); 33 [self.view addSubview:imageView]; 34 imageView.image = [UIImage imageNamed:@"M4"]; 35 }
C.带有placeholder的TextView
1 // 2 // MyTextView.h 3 // MyTextField 4 // 5 // Created by hellovoidworld on 14/12/31. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @interface MyTextView : UITextView 12 13 @property(nonatomic, copy) NSString *placeHolderText; 14 15 @end
1 // 2 // MyTextView.m 3 // MyTextField 4 // 5 // Created by hellovoidworld on 14/12/31. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "MyTextView.h" 10 11 @interface MyTextView() <UITextViewDelegate> 12 13 /** 原来的文本颜色 */ 14 @property(nonatomic, weak) UIColor *originalTextColor; 15 16 @end 17 18 @implementation MyTextView 19 20 // 重写初始化方法,设置代理 21 - (instancetype)init { 22 if (self = [super init]) { 23 self.returnKeyType = UIReturnKeyDone; 24 self.delegate = self; 25 } 26 27 return self; 28 } 29 30 // 重新设置了placeHolderText的时候要重绘一下控件 31 - (void)setPlaceHolderText:(NSString *)placeHolderText { 32 _placeHolderText = placeHolderText; 33 [self setNeedsDisplay]; 34 } 35 36 // 开始编辑,消除placeHolder 37 - (BOOL)textViewShouldBeginEditing:(UITextView *)textView { 38 if ([self.text isEqualToString:self.placeHolderText]) { 39 self.text = nil; 40 self.textColor = self.originalTextColor; 41 } 42 43 return YES; 44 } 45 46 // 结束编辑,如果文本为空,设置placeHolder 47 - (void)textViewDidEndEditing:(UITextView *)textView { 48 [self setNeedsDisplay]; 49 } 50 51 - (void)drawRect:(CGRect)rect { 52 if (self.text.length == 0) { 53 self.text = self.placeHolderText; 54 self.textColor = [UIColor grayColor]; 55 } 56 } 57 58 59 @end
D. 图片水印
1.步骤
(1)在storyboard拖入一个UIImageView, 在控制器代码创建图片上下文
创建一个基于位图的上下文 --> 系统创建一个位图对象
相当于创建了一个新的UIImage对象
(2)画背景
(3)画水印
(4)从上下文取得制作完毕的UIImage对象
(5)结束图片上下文
1 // 2 // UIImage+HW.m 3 // Watermark 4 // 5 // Created by hellovoidworld on 14/12/31. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "UIImage+HW.h" 10 11 @implementation UIImage(HW) 12 13 + (instancetype) image:(NSString *) image withWatermark:(NSString *) watermark { 14 // 取得背景图片 15 UIImage *bgImage = [UIImage imageNamed:image]; 16 17 // 1.开启一个位图上下文 18 UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0); 19 20 // 2.添加背景图片到位图上下文 21 [bgImage drawInRect:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)]; 22 23 // 3.添加水印图片 24 UIImage *watermarkImage = [UIImage imageNamed:watermark]; 25 CGFloat scale = 0.5; 26 CGFloat margin = 50; 27 CGFloat watermarkWidth = watermarkImage.size.width * scale; 28 CGFloat watermarkHeight = watermarkImage.size.width *scale; 29 CGFloat watermarkX = bgImage.size.width - watermarkWidth - margin; 30 CGFloat watermarkY = bgImage.size.height - watermarkHeight - margin; 31 [watermarkImage drawInRect:CGRectMake(watermarkX, watermarkY, watermarkWidth, watermarkHeight)]; 32 33 34 // 4.取得合成后的图片 35 UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); 36 37 // 5.关闭图文上下文 38 UIGraphicsEndImageContext(); 39 40 return resultImage; 41 } 42 43 @end
(6)显示到UIImageView
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 // Do any additional setup after loading the view, typically from a nib. 4 5 UIImage *watermarkedImage = [UIImage image:@"M4" withWatermark:@"a9ec8a13632762d0092abc3ca2ec08fa513dc619"]; 6 7 UIImageView *imageView = [[UIImageView alloc] initWithImage:watermarkedImage]; 8 imageView.frame = CGRectMake(0, 0, 200, 320); 9 [self.view addSubview:imageView]; 10 }
(7)保存图片
a.将image压缩
b.写入文件
1 // 压缩图片为PNG格式的二进制数据 2 NSData *data = UIImagePNGRepresentation(watermarkedImage); 3 4 // 写入文件 5 NSString *path =[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"watermarkedImage.png"]; 6 NSLog(@"%@", path); 7 [data writeToFile:path atomically:YES];
E.头像图片裁剪
裁剪的图片形成新的图片,这里是讲矩形图片裁剪成圆形并带白色边框
1.步骤
(1)背景大圆
(2)小圆裁剪
(3)加入图片
1 /** 创建带有指定宽度和颜色边框的圆形头像图片 */ 2 + (instancetype) imageOfCircleHeadIcon:(NSString *) image withBorderWidth:(CGFloat) borderWidth borderColor:(UIColor *) borderColor { 3 // 取得图片 4 UIImage *headIconImage = [UIImage imageNamed:image]; 5 6 // 开启图片上下文 7 CGFloat backImageWidth = headIconImage.size.width + 2 * borderWidth; 8 CGFloat backImageHeight = headIconImage.size.height + 2 * borderWidth; 9 CGSize backImageSize = CGSizeMake(backImageWidth, backImageHeight); 10 UIGraphicsBeginImageContextWithOptions(backImageSize, NO, 0.0); 11 12 // 描绘背景大圆 13 [borderColor set]; // 设置圆环颜色 14 CGContextRef ctx = UIGraphicsGetCurrentContext(); 15 CGFloat backCircleRadius = backImageWidth * 0.5; // 大圆半径 16 CGFloat backCircleX = backCircleRadius; // 大圆圆心X 17 CGFloat backCircleY = backCircleRadius; // 大圆圆心Y 18 CGContextAddArc(ctx, backCircleX, backCircleY, backCircleRadius, 0, M_PI * 2, 0); 19 CGContextFillPath(ctx); 20 21 // 描绘用来显示图片的小圆 22 CGFloat frontCircleRadius = backCircleRadius - borderWidth; // 图片小圆半径 23 CGFloat frontCircleX = backCircleX; 24 CGFloat frontCircleY = backCircleY; 25 CGContextAddArc(ctx, frontCircleX, frontCircleY, frontCircleRadius, 0, M_PI * 2, 0); 26 27 // 裁剪(后面描绘的将会受到裁剪) 28 CGContextClip(ctx); 29 30 // 添加图片到上下文 31 [headIconImage drawInRect:CGRectMake(borderWidth, borderWidth, headIconImage.size.width, headIconImage.size.height)]; 32 33 // 取得合成后的图片 34 UIImage *headIconResultImage = UIGraphicsGetImageFromCurrentImageContext(); 35 36 // 关闭图片上下文 37 UIGraphicsEndImageContext(); 38 39 return headIconResultImage; 40 }
F.屏幕截图
1.步骤
(1)使用位图上下文
(2)将控制器view的layer渲染到上下文
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
(3)取出图片,保存图片
(4)结束位图上下文
1 /** 点击“屏幕截图” */ 2 - (IBAction)screenShotcut { 3 // 延迟截图, 防止截到的时按钮被按下的状态 4 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 5 6 UIView *view = self.view; 7 8 // 1.开启位图上下文 9 UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0); 10 11 // 2.渲染控制器view的layer到上下文 12 [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 13 14 // 3.从上下文取得图片 15 UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext(); 16 17 // 4.结束上下文 18 UIGraphicsEndImageContext(); 19 20 // 存储图片 21 NSData *data = UIImagePNGRepresentation(screenImage); 22 NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"screenShot.png"]; 23 NSLog(@"%@", path); 24 [data writeToFile:path atomically:YES]; }); 25 26 }
G.drawRect原理
为什么要实现drawRect才能绘图到view上
因为在drawRect方法中才能取得图文相关的上下文
H.背景平铺
1.条纹背景
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 // Do any additional setup after loading the view, typically from a nib. 4 5 // 开启图片上下文 6 CGFloat rowW = self.view.frame.size.width; 7 CGFloat rowH = 30; 8 UIGraphicsBeginImageContextWithOptions(CGSizeMake(rowW, rowH), NO, 0.0); 9 10 CGContextRef ctx = UIGraphicsGetCurrentContext(); 11 // 画色块背景 12 [[UIColor redColor] set]; 13 CGContextAddRect(ctx, CGRectMake(0, 0, rowW, rowH)); 14 CGContextFillPath(ctx); 15 16 // 画线 17 [[UIColor greenColor] set]; 18 CGFloat lineWidth = 2; 19 CGContextSetLineWidth(ctx, lineWidth); 20 CGFloat lineX = 0; 21 CGFloat lineY = rowH - lineWidth; 22 CGContextMoveToPoint(ctx, lineX, lineY); 23 CGContextAddLineToPoint(ctx, rowW - lineX, lineY); 24 CGContextStrokePath(ctx); 25 26 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 27 28 // 使用平铺方式铺满屏幕 29 [self.view setBackgroundColor:[UIColor colorWithPatternImage:image]]; 30 31 UIGraphicsEndImageContext(); 32 }