drawRect:绘图
drawRect:绘图
作用:专门用来绘图 什么时候调用:当View显示的时候调用(ViewWillAppear和ViewDidAppear之间) 参数rect:当View的bounds 在drawRect方法当中系统已经帮你创建一个跟View相关联的上下文(Layer上下文),只要获取上下文就可以了
带有边框的图片裁剪
- 步骤:
- 1.假设边框宽度为BorderW
- 2.开启的图片上下文的尺寸就应该是原始图片的宽高分别加上两倍的BorderW,这样开启的目的是为了不让原始图片变形.
- 3.在上下文上面添加一个圆形填充路径.位置从0,0点开始,宽高和上下文尺寸一样大.设置颜色为要设置的边框颜色.
- 4.继续在上下文上面添加一个圆形路径,这个路径为裁剪路径. 它的x,y分别从BorderW这个点开始.宽度和高度分别和原始图片的宽高一样大. 将绘制的这个路径设为裁剪区域.
- 5.把原始路径绘制到上下文当中.绘制的位置和是裁剪区域的位置相同,x,y分别从border开始绘制.
- 6.从上下文状态当中取出图片.
- 7.关闭上下文状态.
代码实现
//
// UIImage+image.h
#import <UIKit/UIKit.h>
@interface UIImage (image)
/**
根据传入的图片,生成一终带有边框的圆形图片
参数:边框宽度,边框颜色,原始图片
*/
+ (UIImage *)imageWithBorderW:(CGFloat)borderW borderColor:(UIColor *)color image:(UIImage *)image;
@end
//
// UIImage+image.m
#import "UIImage+image.h"
@implementation UIImage (image)
/**
根据传入的图片,生成一终带有边框的圆形图片
参数:边框宽度,边框颜色,原始图片
*/
+ (UIImage *)imageWithBorderW:(CGFloat)borderW borderColor:(UIColor *)color image:(UIImage *)image{
//1.开启一个和原始图片一样大小的位图上下文.
CGSize size = CGSizeMake(image.size.width + 2 *borderW, image.size.height + 2 * borderW);
UIGraphicsBeginImageContextWithOptions(size,NO,0);
//2.绘制一个大圆,填充
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)];
[color set];
[path fill];
//3.添加一个裁剪区域.
path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderW, borderW, image.size.width, image.size.height)];
[path addClip];
//4.把图片绘制到裁剪区域当中.
[image drawAtPoint:CGPointMake(borderW, borderW)];
//5.生成一张新图片.
UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();
//6.关闭上下文.
UIGraphicsEndImageContext();
return clipImage;
}
@end
1.drawRect:基本使用
自定义绘图View的步骤 新建一个类,继承UIView 实现drawRect:方法,然后在这个方法里写(4点) 1.获取上下文 2.描述路径 3.把描述路径添加到上下文当中 4.把上下文的内容显示到View上(渲染到View的Layer上)
drawLine画直线
// 画直线
- (void)drawLine{
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
UIBezierPath *path = [UIBezierPath bezierPath];
// 设置起点 + 添加一根线到终点
[path moveToPoint:CGPointMake(50, 280)];
[path addLineToPoint:CGPointMake(250, 50)];
// 画第二条线
[path addLineToPoint:CGPointMake(200, 280)];
// 上下文的状态
// 设置线宽
CGContextSetLineWidth(ctx, 10);
// 设置线的连接样式
CGContextSetLineJoin(ctx, kCGLineJoinRound);
// 设置线的顶角样式
CGContextSetLineCap(ctx, kCGLineCapRound);
// 设置颜色
[[UIColor redColor] set];
// 3.把描述的内容添加到上下文
// UIBezierPath:UIKit框架 ,CGPathRef:CoreGraphics框架
CGContextAddPath(ctx, path.CGPath);
// 4.把上下文内容显示到View上(渲染到View的layer)
CGContextStrokePath(ctx);
}
drawCurve画曲线
// 画曲线
- (void)drawCurve{
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
UIBezierPath *path = [UIBezierPath bezierPath];
// 画曲线(controlPoint:弯曲方向点)
[path moveToPoint:CGPointMake(50, 280)];
[path addQuadCurveToPoint:CGPointMake(250, 280) controlPoint:CGPointMake(50, 50)];
// 3.把描述内容添加到上下文当中
CGContextAddPath(ctx, path.CGPath);
// 4.把上下文的内容显示到View上(渲染到View的layer上)
// 渲染两种方式(Stroke路径渲染,Fill内容渲染)📚⏰
CGContextStrokePath(ctx);
}
drawRect画矩形
// 画矩形
- (void)drawRect{
CGContextRef ctx = UIGraphicsGetCurrentContext();
//UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 100, 50)];
// 画圆角矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 50, 50) cornerRadius:25];
[[UIColor redColor] set];
CGContextAddPath(ctx, path.CGPath);
//CGContextStrokePath(ctx);
CGContextFillPath(ctx);
}
**drawEllipse画椭圆**
// 画椭圆
- (void)drawEllipse{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 50)];
// 使用UIBezierPath提供的绘图方法进行绘制(绘图👌)
[path stroke];
}
drawRidan画弧度
// 画弧度
- (void)drawRidan{
CGRect rect = self.bounds;
CGPoint center = CGPointMake(rect.size.width *0.5, rect.size.width *0.5);
CGFloat radius = rect.size.width *0.5 - 10;
/*
clockwise:方向(顺时针或是逆时针)
*/
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
[path stroke];
}
drawFan画扇形
// 画扇形
- (void)drawFan{
CGRect rect = self.bounds;
CGPoint center = CGPointMake(rect.size.width *0.5, rect.size.width *0.5);
CGFloat radius = rect.size.width *0.5 - 10;
/*
clockwise:方向(顺时针或是逆时针)
*/
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
[path addLineToPoint:center];
[[UIColor redColor] set];
[path fill];
}
drawArc下载进度
// 画弧
- (void)drawArc{
CGRect rect = self.bounds;
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height *0.5);
CGFloat radius = rect.size.width * 0.5 - 10;
CGFloat startA = -M_PI_2;
CGFloat angle = self.progressValue * M_PI*2;
CGFloat endA = startA +angle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
// 3.把描述路径添加到上下文当中
CGContextAddPath(ctx, path.CGPath);
// 4.把上下文的内容渲染到View的layer上
CGContextStrokePath(ctx);
}
- (void)setProgressValue:(CGFloat)progressValue{
_progressValue = progressValue;
// 重绘(系统自动帮你调用drawRect)*+
[self setNeedsDisplay];📚
}
2.饼图
@implementation PieView
- (void)drawRect:(CGRect)rect {
NSArray *dataAarry = @[@25,@25,@50];
// 画第一个扇形
CGPoint center = CGPointMake(rect.size.width *0.5, rect.size.height *0.5);
CGFloat radius = rect.size.width *0.5 - 10;
CGFloat startA = 0;
CGFloat angle = 0;
CGFloat endA = 0;
for (NSNumber *num in dataAarry) {
startA = endA;
angle = num.intValue / 100.0 *M_PI *2;
endA = startA +angle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
[[self randomColor] set];
[path addLineToPoint:center];
[path fill];
}
}
// 触摸*+
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 重绘*+
[self setNeedsDisplay];
}
// 设置随机颜色📚*+
- (UIColor *)randomColor{
CGFloat r = arc4random_uniform(256) / 255.0;
CGFloat g = arc4random_uniform(256) / 255.0;
CGFloat b = arc4random_uniform(256) / 255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
}
3.UIKit绘图
drawText
📚
- (void)drawText{
CGRect rect = self.bounds;
NSString *str = @"孙永会孙永会孙永会孙永会孙永会";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 设置字体大小
dict[NSFontAttributeName] = [UIFont systemFontOfSize:30];
// 设置颜色
dict[NSForegroundColorAttributeName] = [UIColor redColor];
// 设置描边
dict[NSStrokeColorAttributeName] = [UIColor greenColor];
dict[NSStrokeWidthAttributeName] = @2;
// 设置阴影
NSShadow *shaw = [[NSShadow alloc] init];
shaw.shadowColor = [UIColor blueColor];
shaw.shadowOffset = CGSizeMake(5, 5);
shaw.shadowBlurRadius = 2;
dict[NSShadowAttributeName] = shaw;
//[str drawAtPoint:CGPointZero withAttributes:dict];
// 用drawInRect:rect会自动换行,用drawAtPoint不会自动换行
[str drawInRect:rect withAttributes:dict];
}
drawImage
// 画图片
- (void)drawImage{
CGRect rect = self.bounds;
UIImage *image = [UIImage imageNamed:@"阿狸头像"];
// 图片裁剪
UIRectClip(CGRectMake(10, 10, 100, 100));📚
// drawAtPoint:绘制的是原始图片的大小
[image drawAtPoint:CGPointZero];📚
// drawInRect:填充到给定区域
//[image drawInRect:rect];📚
// 平铺
//[image drawAsPatternInRect:rect];📚
}
4.定时器(雪花效果)
@implementation DrawSnowView
- (void)awakeFromNib{
// 定时器方法一:📚
//[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(ChangY) userInfo:nil repeats:YES];
// 定时器方法二:📚
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(ChangY)];
// 必须添加到主运行循环当中
// 当每一次屏幕刷新的时候就会调用指定的方法(屏幕每一秒刷新60次)
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];📚
// setNeedsDisplay:会调用drawRect,但是并不是立马调用,只是设了一个标示,当下一次屏幕刷新的时候才去调用drawRect
}
static int _snowY = 0;
- (void)ChangY{
_snowY += 10;
if (_snowY > [UIScreen mainScreen].bounds.size.height) {
_snowY = 0;
}
// 重绘
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed:@"flake"];
[image drawAtPoint:CGPointMake(0, _snowY)];
}
@end
5.图片加水印
@implementation LNImageViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 0.加载图片
UIImage *image = [UIImage imageNamed:@"阿狸头像"];
📚
// 1.开启一个跟图片原始大小的上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);*+
// 2.把图片绘制到上下文当中
[image drawAtPoint:CGPointZero];*+
// 3.把文字绘制到上下文当中
NSString *str = @"Learning Point";
[str drawAtPoint:CGPointMake(10, 170) withAttributes:nil];
// 4.从上下文当中生成一张图片(把上下文当中绘制的所有内容,生成一张图片)
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();*+
// 5.关闭上下文
UIGraphicsEndImageContext();*+
// 6.赋值
self.imageView.image = newImage;*+
}
6.图片截屏
/*
图片截屏
监听
方法一:使用拖动手势监听📚
// 把上下文的内容渲染到View的Layer上*+
[self.imageView.layer renderInContext:ctx];
*/
#import "ImageScreenShotsVC.h"
@interface ImageScreenShotsVC ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
/** 开始时手指点 */
@property (nonatomic, assign) CGPoint startP;
/** 遮罩View */
@property (nonatomic, weak) UIView *coverView;
@end
@implementation ImageScreenShotsVC
//懒加载遮盖,保存遮盖只有一份.
-(UIView *)coverView{
if (_coverView == nil) {
UIView *cover = [[UIView alloc] init];
cover.backgroundColor = [UIColor blackColor];
cover.alpha = 0.7;
[self.view addSubview:cover];
_coverView = cover;
}
return _coverView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView.userInteractionEnabled = YES;
// 添加手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; [self.imageView addGestureRecognizer:pan];
}
- (void)panGesture:(UIPanGestureRecognizer *)pan{📚
// 获取当前点
CGPoint curP = [pan locationInView:self.imageView];
if (pan.state == UIGestureRecognizerStateBegan) {
// 开始点
CGPoint startP = curP;
self.startP = startP;
} else if (pan.state == UIGestureRecognizerStateChanged){
CGFloat x = self.startP.x;
CGFloat y = self.startP.y;
CGFloat W = curP.x - self.startP.x;
CGFloat H = curP.y - self.startP.y;
CGRect rect = CGRectMake(x, y, W, H);
// 添加一个UIView遮罩
self.coverView.frame = rect;
} else if (pan.state == UIGestureRecognizerStateEnded){
// 当手指开时.把遮盖的范围当做是一个裁剪区域.
// 把图片绘制到上下文中.超过裁剪范围的图片会被裁剪掉.
// 重新生成一张新的图片.给原来的UIImageView赋值.
// 创建一个和原始图片大小的上下文 UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, 0);
// 设置剪切区域
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.coverView.frame];
[path addClip];📚
//把图片绘制到上下文当中.超过裁剪区域的部分会自动裁剪掉
//当前是UIImageView,它也是UIView.所以也必须得要用渲染的方式绘制
// 获取当前的上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 把上下文的内容渲染到View的Layer上*+
[self.imageView.layer renderInContext:ctx];📚
// 从上下文当中生成一张图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
// 给原来的图片赋值
self.imageView.image = newImage;
// 把遮罩移除
[self.coverView removeFromSuperview];
}
}
@end
7.图片擦除
#import "ContextClearRectVC.h"
@interface ContextClearRectVC ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ContextClearRectVC
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView.userInteractionEnabled = YES;
// 添加拖动手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
[self.imageView addGestureRecognizer:pan];
}
- (void)panGesture:(UIPanGestureRecognizer *)pan{
// 获取当前点
CGPoint curP = [pan locationInView:self.imageView];
// 确定擦除区域
CGFloat rectWH = 30;
CGFloat x = curP.x - rectWH *0.5;
CGFloat y = curP.y - rectWH *0.5;
CGRect rect = CGRectMake(x, y, rectWH, rectWH);
// 生成带有透明擦除区域的图片
// 1.开启位图上下文
UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, 0);
// 2.获取当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 3.渲染
[self.imageView.layer renderInContext:ctx];
// 4.设置擦除区域📚
CGContextClearRect(ctx, rect);
// 5.从上下文当中取出一张图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// 6.关闭位图上下文
UIGraphicsEndImageContext();
// 7.给原图片赋值
self.imageView.image = newImage;
}
@end
8.画板
作用:专门用来绘图
什么时候调用:当View显示的时候调用(ViewWillAppear和ViewDidAppear之间)
参数rect:当View的bounds
在drawRect方法当中系统已经帮你创建一个跟View相关联的上下文(Layer上下文),只要获取上下文就可以了
带有边框的图片裁剪
- 步骤:
1.假设边框宽度为BorderW
2.开启的图片上下文的尺寸就应该是原始图片的宽高分别加上两倍的BorderW,这样开启的目的是为了不让原始图片变形.
3.在上下文上面添加一个圆形填充路径.位置从0,0点开始,宽高和上下文尺寸一样大.设置颜色为要设置的边框颜色.
4.继续在上下文上面添加一个圆形路径,这个路径为裁剪路径.它的x,y分别从BorderW这个点开始.宽度和高度分别和原始图片的宽高一样大. 将绘制的这个路径设为裁剪区域.
5.把原始路径绘制到上下文当中.绘制的位置和是裁剪区域的位置相同,x,y分别从border开始绘制.
6.从上下文状态当中取出图片.
7.关闭上下文状态.
代码实现
//
// UIImage+image.h
#import <UIKit/UIKit.h>
@interface UIImage (image)
/**
根据传入的图片,生成一终带有边框的圆形图片
参数:边框宽度,边框颜色,原始图片
*/
+ (UIImage *)imageWithBorderW:(CGFloat)borderW borderColor:(UIColor *)color image:(UIImage *)image;
@end
//
// UIImage+image.m
#import "UIImage+image.h"
@implementation UIImage (image)
/**
根据传入的图片,生成一终带有边框的圆形图片
参数:边框宽度,边框颜色,原始图片
*/
+ (UIImage *)imageWithBorderW:(CGFloat)borderW borderColor:(UIColor *)color image:(UIImage *)image{
//1.开启一个和原始图片一样大小的位图上下文.
CGSize size = CGSizeMake(image.size.width + 2 *borderW, image.size.height + 2 * borderW);
UIGraphicsBeginImageContextWithOptions(size,NO,0);
//2.绘制一个大圆,填充
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)];
[color set];
[path fill];
//3.添加一个裁剪区域.
path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderW, borderW, image.size.width, image.size.height)];
[path addClip];
//4.把图片绘制到裁剪区域当中.
[image drawAtPoint:CGPointMake(borderW, borderW)];
//5.生成一张新图片.
UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();
//6.关闭上下文.
UIGraphicsEndImageContext();
return clipImage;
}
@end
1.drawRect:基本使用
自定义绘图View的步骤
新建一个类,继承UIView
实现drawRect:方法,然后在这个方法里写(4点)
1.获取上下文
2.描述路径
3.把描述路径添加到上下文当中
4.把上下文的内容显示到View上(渲染到View的Layer上)
- drawLine画直线
// 画直线
- (void)drawLine{
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
UIBezierPath *path = [UIBezierPath bezierPath];
// 设置起点 + 添加一根线到终点
[path moveToPoint:CGPointMake(50, 280)];
[path addLineToPoint:CGPointMake(250, 50)];
// 画第二条线
[path addLineToPoint:CGPointMake(200, 280)];
// 上下文的状态
// 设置线宽
CGContextSetLineWidth(ctx, 10);
// 设置线的连接样式
CGContextSetLineJoin(ctx, kCGLineJoinRound);
// 设置线的顶角样式
CGContextSetLineCap(ctx, kCGLineCapRound);
// 设置颜色
[[UIColor redColor] set];
// 3.把描述的内容添加到上下文
// UIBezierPath:UIKit框架 ,CGPathRef:CoreGraphics框架
CGContextAddPath(ctx, path.CGPath);
// 4.把上下文内容显示到View上(渲染到View的layer)
CGContextStrokePath(ctx);
}
- drawCurve画曲线
// 画曲线
- (void)drawCurve{
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
UIBezierPath *path = [UIBezierPath bezierPath];
// 画曲线(controlPoint:弯曲方向点)
[path moveToPoint:CGPointMake(50, 280)];
[path addQuadCurveToPoint:CGPointMake(250, 280) controlPoint:CGPointMake(50, 50)];
// 3.把描述内容添加到上下文当中
CGContextAddPath(ctx, path.CGPath);
// 4.把上下文的内容显示到View上(渲染到View的layer上)
// 渲染两种方式(Stroke路径渲染,Fill内容渲染)📚⏰
CGContextStrokePath(ctx);
}
- drawRect画矩形
// 画矩形
- (void)drawRect{
CGContextRef ctx = UIGraphicsGetCurrentContext();
//UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 100, 50)];
// 画圆角矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 50, 50) cornerRadius:25];
[[UIColor redColor] set];
CGContextAddPath(ctx, path.CGPath);
//CGContextStrokePath(ctx);
CGContextFillPath(ctx);
}
- drawEllipse画椭圆
// 画椭圆
- (void)drawEllipse{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 50)];
// 使用UIBezierPath提供的绘图方法进行绘制(绘图👌)
[path stroke];
}
- drawRidan画弧度
// 画弧度
- (void)drawRidan{
CGRect rect = self.bounds;
CGPoint center = CGPointMake(rect.size.width *0.5, rect.size.width *0.5);
CGFloat radius = rect.size.width *0.5 - 10;
/*
clockwise:方向(顺时针或是逆时针)
*/
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
[path stroke];
}
- drawFan画扇形
// 画扇形
- (void)drawFan{
CGRect rect = self.bounds;
CGPoint center = CGPointMake(rect.size.width *0.5, rect.size.width *0.5);
CGFloat radius = rect.size.width *0.5 - 10;
/*
clockwise:方向(顺时针或是逆时针)
*/
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
[path addLineToPoint:center];
[[UIColor redColor] set];
[path fill];
}
- drawArc下载进度
// 画弧
- (void)drawArc{
CGRect rect = self.bounds;
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height *0.5);
CGFloat radius = rect.size.width * 0.5 - 10;
CGFloat startA = -M_PI_2;
CGFloat angle = self.progressValue * M_PI*2;
CGFloat endA = startA +angle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
// 3.把描述路径添加到上下文当中
CGContextAddPath(ctx, path.CGPath);
// 4.把上下文的内容渲染到View的layer上
CGContextStrokePath(ctx);
}
- (void)setProgressValue:(CGFloat)progressValue{
_progressValue = progressValue;
// 重绘(系统自动帮你调用drawRect)*+
[self setNeedsDisplay];📚
}
2.饼图
@implementation PieView
- (void)drawRect:(CGRect)rect {
NSArray *dataAarry = @[@25,@25,@50];
// 画第一个扇形
CGPoint center = CGPointMake(rect.size.width *0.5, rect.size.height *0.5);
CGFloat radius = rect.size.width *0.5 - 10;
CGFloat startA = 0;
CGFloat angle = 0;
CGFloat endA = 0;
for (NSNumber *num in dataAarry) {
startA = endA;
angle = num.intValue / 100.0 *M_PI *2;
endA = startA +angle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
[[self randomColor] set];
[path addLineToPoint:center];
[path fill];
}
}
// 触摸*+
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 重绘*+
[self setNeedsDisplay];
}
// 设置随机颜色📚*+
- (UIColor *)randomColor{
CGFloat r = arc4random_uniform(256) / 255.0;
CGFloat g = arc4random_uniform(256) / 255.0;
CGFloat b = arc4random_uniform(256) / 255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
}
3.UIKit绘图
- drawText
📚
- (void)drawText{
CGRect rect = self.bounds;
NSString *str = @"孙永会孙永会孙永会孙永会孙永会";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 设置字体大小
dict[NSFontAttributeName] = [UIFont systemFontOfSize:30];
// 设置颜色
dict[NSForegroundColorAttributeName] = [UIColor redColor];
// 设置描边
dict[NSStrokeColorAttributeName] = [UIColor greenColor];
dict[NSStrokeWidthAttributeName] = @2;
// 设置阴影
NSShadow *shaw = [[NSShadow alloc] init];
shaw.shadowColor = [UIColor blueColor];
shaw.shadowOffset = CGSizeMake(5, 5);
shaw.shadowBlurRadius = 2;
dict[NSShadowAttributeName] = shaw;
//[str drawAtPoint:CGPointZero withAttributes:dict];
// 用drawInRect:rect会自动换行,用drawAtPoint不会自动换行
[str drawInRect:rect withAttributes:dict];
}
- drawImage
// 画图片
- (void)drawImage{
CGRect rect = self.bounds;
UIImage *image = [UIImage imageNamed:@"阿狸头像"];
// 图片裁剪
UIRectClip(CGRectMake(10, 10, 100, 100));📚
// drawAtPoint:绘制的是原始图片的大小
[image drawAtPoint:CGPointZero];📚
// drawInRect:填充到给定区域
//[image drawInRect:rect];📚
// 平铺
//[image drawAsPatternInRect:rect];📚
}
4.定时器(雪花效果)
@implementation DrawSnowView
- (void)awakeFromNib{
// 定时器方法一:📚
//[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(ChangY) userInfo:nil repeats:YES];
// 定时器方法二:📚
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(ChangY)];
// 必须添加到主运行循环当中
// 当每一次屏幕刷新的时候就会调用指定的方法(屏幕每一秒刷新60次)
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];📚
// setNeedsDisplay:会调用drawRect,但是并不是立马调用,只是设了一个标示,当下一次屏幕刷新的时候才去调用drawRect
}
static int _snowY = 0;
- (void)ChangY{
_snowY += 10;
if (_snowY > [UIScreen mainScreen].bounds.size.height) {
_snowY = 0;
}
// 重绘
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed:@"flake"];
[image drawAtPoint:CGPointMake(0, _snowY)];
}
@end
5.图片加水印
@implementation LNImageViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 0.加载图片
UIImage *image = [UIImage imageNamed:@"阿狸头像"];
📚
// 1.开启一个跟图片原始大小的上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);*+
// 2.把图片绘制到上下文当中
[image drawAtPoint:CGPointZero];*+
// 3.把文字绘制到上下文当中
NSString *str = @"Learning Point";
[str drawAtPoint:CGPointMake(10, 170) withAttributes:nil];
// 4.从上下文当中生成一张图片(把上下文当中绘制的所有内容,生成一张图片)
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();*+
// 5.关闭上下文
UIGraphicsEndImageContext();*+
// 6.赋值
self.imageView.image = newImage;*+
}
6.图片截屏
/*
图片截屏
监听
方法一:使用拖动手势监听📚
// 把上下文的内容渲染到View的Layer上*+
[self.imageView.layer renderInContext:ctx];
*/
#import "ImageScreenShotsVC.h"
@interface ImageScreenShotsVC ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
/** 开始时手指点 */
@property (nonatomic, assign) CGPoint startP;
/** 遮罩View */
@property (nonatomic, weak) UIView *coverView;
@end
@implementation ImageScreenShotsVC
//懒加载遮盖,保存遮盖只有一份.
-(UIView *)coverView{
if (_coverView == nil) {
UIView *cover = [[UIView alloc] init];
cover.backgroundColor = [UIColor blackColor];
cover.alpha = 0.7;
[self.view addSubview:cover];
_coverView = cover;
}
return _coverView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView.userInteractionEnabled = YES;
// 添加手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; [self.imageView addGestureRecognizer:pan];
}
- (void)panGesture:(UIPanGestureRecognizer *)pan{📚
// 获取当前点
CGPoint curP = [pan locationInView:self.imageView];
if (pan.state == UIGestureRecognizerStateBegan) {
// 开始点
CGPoint startP = curP;
self.startP = startP;
} else if (pan.state == UIGestureRecognizerStateChanged){
CGFloat x = self.startP.x;
CGFloat y = self.startP.y;
CGFloat W = curP.x - self.startP.x;
CGFloat H = curP.y - self.startP.y;
CGRect rect = CGRectMake(x, y, W, H);
// 添加一个UIView遮罩
self.coverView.frame = rect;
} else if (pan.state == UIGestureRecognizerStateEnded){
// 当手指开时.把遮盖的范围当做是一个裁剪区域.
// 把图片绘制到上下文中.超过裁剪范围的图片会被裁剪掉.
// 重新生成一张新的图片.给原来的UIImageView赋值.
// 创建一个和原始图片大小的上下文 UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, 0);
// 设置剪切区域
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.coverView.frame];
[path addClip];📚
//把图片绘制到上下文当中.超过裁剪区域的部分会自动裁剪掉
//当前是UIImageView,它也是UIView.所以也必须得要用渲染的方式绘制
// 获取当前的上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 把上下文的内容渲染到View的Layer上*+
[self.imageView.layer renderInContext:ctx];📚
// 从上下文当中生成一张图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
// 给原来的图片赋值
self.imageView.image = newImage;
// 把遮罩移除
[self.coverView removeFromSuperview];
}
}
@end
7.图片擦除
#import "ContextClearRectVC.h"
@interface ContextClearRectVC ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ContextClearRectVC
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView.userInteractionEnabled = YES;
// 添加拖动手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
[self.imageView addGestureRecognizer:pan];
}
- (void)panGesture:(UIPanGestureRecognizer *)pan{
// 获取当前点
CGPoint curP = [pan locationInView:self.imageView];
// 确定擦除区域
CGFloat rectWH = 30;
CGFloat x = curP.x - rectWH *0.5;
CGFloat y = curP.y - rectWH *0.5;
CGRect rect = CGRectMake(x, y, rectWH, rectWH);
// 生成带有透明擦除区域的图片
// 1.开启位图上下文
UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, 0);
// 2.获取当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 3.渲染
[self.imageView.layer renderInContext:ctx];
// 4.设置擦除区域📚
CGContextClearRect(ctx, rect);
// 5.从上下文当中取出一张图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// 6.关闭位图上下文
UIGraphicsEndImageContext();
// 7.给原图片赋值
self.imageView.image = newImage;
}
@end