ReactiveCocoaiOS开发

drawRect:绘图

2017-01-12  本文已影响777人  CoderLNHui

drawRect:绘图

作用:专门用来绘图 什么时候调用:当View显示的时候调用(ViewWillAppear和ViewDidAppear之间) 参数rect:当View的bounds 在drawRect方法当中系统已经帮你创建一个跟View相关联的上下文(Layer上下文),只要获取上下文就可以了

带有边框的图片裁剪

代码实现

//

// 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上下文),只要获取上下文就可以了

带有边框的图片裁剪

代码实现


//

//  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上)


// 画直线
- (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);
}
// 画曲线
- (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);
}
// 画矩形
- (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);
}
// 画椭圆
- (void)drawEllipse{ 
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 50)];

    // 使用UIBezierPath提供的绘图方法进行绘制(绘图👌)
    [path stroke];
}
// 画弧度
- (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];
}
// 画扇形

- (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];
}

// 画弧
- (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绘图


📚
- (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];
}

// 画图片
- (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
上一篇下一篇

猜你喜欢

热点阅读