
·您现在的位置: 江北区云翼计算机软件开发服务部 >> 文章中心 >> 网站建设 >> app软件开发 >> IOS开发 >> iOSUI进阶05
// 什么时候调用:当前控件即将显示的时候才会调用这个方法绘制
// 作用:绘制内容,以后只要想在一个view中绘制内容,必须在drawRect里面绘制
- (void)drawRect:(CGRect)rect {
// 绘制曲线
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
UIBezierPath *path = [UIBezierPath bezierPath];
// 设置起点
[path moveToPoint:CGPointMake(10, 125)];
// 描述曲线
[path addQuadCurveToPoint:CGPointMake(240, 125) controlPoint:CGPointMake(125, 240)];
[path addLineToPoint:CGPointMake(10, 125)];
// 3.添加路径到上下文
CGContextAddPath(ctx, path.CGPath);
// 设置绘图状态,一定要再渲染之前
// 设置颜色
[[UIColor redColor] setStroke];
// 设置线段的宽度
CGContextSetLineWidth(ctx, 15);
// 设置线段的顶角样式
CGContextSetLineCap(ctx, kCGLineCaPRound);
// 设置连接样式
CGContextSetLineJoin(ctx, kCGLineJoinRound);
// 4.渲染上下文
CGContextStrokePath(ctx);
}
// 绘制两条路径的方法
- (void)drawTwoLine
{
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径,一个路径中可以保存多条线段
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 10)];
[path addLineToPoint:CGPointMake(20, 20)];
// 3.把路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
// 一根线对应一个路径,只要绘制的线不连接,最好使用一根线对应一个路径的方法
path = [UIBezierPath bezierPath];
// 拼接另一根直线
// 默认下一根线的起点就是上一根线的终点
// 设置第二根线的起点
// [path moveToPoint:CGPointMake(20, 20)];
// 如果想要绘制不连接的线,重新设置起点
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(20, 200)];
// 3.把路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
// 4.渲染上下文
CGContextStrokePath(ctx);
}
// 画圆弧
// Center圆心
// radius:半径
// startAngle起始角度
// endAngle:结束角度
// clockwise:Yes 顺时针 No逆时针
CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:NO];
[path1 stroke];
// 画扇形
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
[path addLineToPoint:center];
[path addLineToPoint:CGPointMake(self.bounds.size.height * 0.5 + 100, self.bounds.size.height * 0.5)];
// 关闭路径:从路径的终点连接到起点
[path closePath];
// 设置填充颜色
[[UIColor redColor] setFill];
// 设置描边颜色
[[UIColor greenColor] setStroke];
// [path stroke];
// 如果路径不是封闭的,默认会关闭路径
[path fill];
#import "PieView.h"
@implementation PieView
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//重绘
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
// Drawing code
NSArray *data = @[@25,@25,@20,@30];
//圆心
CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
//角度
CGFloat radius = self.bounds.size.width * 0.5;
CGFloat startA = 0;
CGFloat endA = 0;
CGFloat angle = 0;
for (NSNumber *num in data) {
// 画一个扇形
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];
[path addLineToPoint:center];
// set:同时设置描边和填充颜色
[[self randomColor] set];
[path fill];
}
}
// 随机颜色
- (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];
}
@end
效果图:
- (void)drawRect:(CGRect)rect {
NSString *str = @"hello!";
// Attributes:属性
// 给一个字符串添加属性,可以叫富文本,颜色,字体大小,空心,阴影
// 利用这个属性字典给文本添加属性
NSMutableDictionary *strAttr = [NSMutableDictionary dictionary];
// key,value
// 如何找到设置文本的属性key
// 描述了字体
strAttr[NSFontAttributeName] = [UIFont boldSystemFontOfSize:50];
// 设置描边的颜色和宽度
strAttr[NSStrokeWidthAttributeName] = @1;
strAttr[NSStrokeColorAttributeName] = [UIColor redColor];
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor yellowColor];
shadow.shadowOffset = CGSizeMake(10, 10);
shadow.shadowBlurRadius = 5;
// 阴影
strAttr[NSShadowAttributeName] = shadow;
// 文字颜色
strAttr[NSForegroundColorAttributeName] = [UIColor redColor];
[str drawAtPoint:CGPointZero withAttributes:strAttr];
}
效果图:
#import "SnowView.h"
@implementation SnowView
- (void)awakeFromNib
{
// 设置定时器
// [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
// 0.1 setNeedsDisplay 绑定一个标识,等待下次刷新的时候才会调用drawRect方法
// 0.15 屏幕的刷新时间
// 定时器
// 每次屏幕刷新的时候就会调用,屏幕一秒刷新60次
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
// 只要把定时器添加到主运行循环就能自动执行
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
// setNeedsDisplay:底层并不会马上调用drawRect,只会给当前的控件绑定一个刷新的标识,每次屏幕刷新的时候,就会把绑定了刷新(重绘)标识的控件重新刷新(绘制)一次,就会调用drawRect去重绘
// 如果以后每隔一段时间需要重绘,一般不使用NSTimer,使用CADisplayLink,不会刷新的时候有延迟
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
static CGFloat snowY = 0;
UIImage *image = [UIImage imageNamed:@"雪花"];
[image drawAtPoint:CGPointMake(0, snowY)];
snowY += 10;
if (snowY > rect.size.height) {
snowY = 0;
}
}
效果图:
#import "DrawView.h"
@implementation DrawView
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 125)];
[path addLineToPoint:CGPointMake(240, 125)];
// 3.把路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
// 保存当前上下文的默认状态
CGContextSaveGState(ctx);
// 设置状态
[[UIColor redColor] set];
CGContextSetLineWidth(ctx, 20);
// 渲染上下文
CGContextStrokePath(ctx);
// 创建第二根路径
path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(125, 10)];
[path addLineToPoint:CGPointMake(125, 240)];
// 添加到上下文
CGContextAddPath(ctx, path.CGPath);
// 恢复下上下文状态
// 取出之前的保存的状态覆盖掉当前的状态
CGContextRestoreGState(ctx);
// [[UIColor blackColor] set];
// CGContextSetLineWidth(ctx, 1);
// 4.渲染上下文到view的layer
// 在渲染之前,系统会查看下上下文的状态,根据状态去渲染
CGContextStrokePath(ctx);
}
@end
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, weak) UIView *cover;
@property (nonatomic, assign) CGPoint oriP;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UIView *view1;
@end
@implementation ViewController
- (UIView *)cover
{
if (_cover == nil) {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor blackColor];
view.alpha = 0.5;
_cover = view;
[self.view addSubview:view];
}
return _cover;
}
- (IBAction)pan:(UIPanGestureRecognizer *)sender {
// 获取下当前的触摸
CGPoint curP = [sender locationInView:_imageView];
if (sender.state == UIGestureRecognizerStateBegan) {
// 记录下一开始的位置
_oriP = curP;
}
// 计算下黑色蒙版的frame
CGFloat w = curP.x - _oriP.x;
CGFloat h = curP.y - _oriP.y;
self.cover.frame = CGRectMake(_oriP.x, _oriP.y, w, h);
if (sender.state == UIGestureRecognizerStateEnded) { // 手指抬起
// 裁剪图片,生成一张新图片
// 开启位图上下文
UIGraphicsBeginImageContextWithOptions(_imageView.bounds.size, NO, 0);
// 设置裁剪区域
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.cover.frame];
[path addClip];
// 绘制图片
[_imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
// 生成图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
_imageView.image = image;
[self.cover removeFromSuperview];
}
}
@end
效果图:截屏前
效果图:截屏后
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 只要用户手指在图片上拖动.就会调用
- (IBAction)pan:(UIPanGestureRecognizer *)sender {
// 拖动的时候,擦除图片的某一部分
// 获取手指的触摸点
CGPoint curP = [sender locationInView:sender.view];
// 计算擦除的frame
CGFloat wh = 30;
CGFloat x = curP.x - wh * 0.5;
CGFloat y = curP.y - wh * 0.5;
CGRect frame = CGRectMake(x, y, wh, wh);
// 开启位图上下文
UIGraphicsBeginImageContextWithOptions(sender.view.bounds.size, NO, 0);
// 获取当前的上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 把控件上的内容渲染到上下文
[sender.view.layer renderInContext:ctx];
// 清除上下文中某一部分的内容
CGContextClearRect(ctx, frame);
// 生成一张新的图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
// 重新显示到UIImageView
UIImageView *imageV = (UIImageView *)sender.view;
imageV.image = image;
}
@end
效果图:擦除前:
效果图:擦除部分后: