接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线
创建项目 起名testAddLine
接下来我们在默认生成的ViewController中添加一张图片 待用
同时添加一个按钮
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIImageView *imageV = [[UIImageView alloc]initWithFrame:CGRectMake(10, 120, screen_Width-20, screen_Height-150)]; imageV.image = [UIImage imageNamed:@"640-960-1.jpg"]; [self.view addSubview:imageV]; UIButton *testBtn = [[UIButton alloc]initWithFrame:CGRectMake(screen_Width/2.0-60, 60, 120, 36)]; [testBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [testBtn setTitle:@"添加直线" forState:UIControlStateNormal]; [testBtn addTarget:self action:@selector(addLineAct:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:testBtn]; } - (void)addLineAct:(id)sender{ NSLog(@"测试按钮"); }
创建几个变量
@property(nonatomic,strong) NSMutableArray * completeLines; //已经画好的线条 存入数组 @property(nonatomic,strong) NSMutableDictionary* LinesInProscess; //正在画的线条 存入字典 @property(nonatomic,strong) UIColor *lineColor;//线条颜色 @property (nonatomic)float lineWidth;//线条的粗细
//初始化 - (id)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { //初始化变量 _completeLines = [[NSMutableArray alloc]init]; _LinesInProscess = [[NSMutableDictionary alloc]init]; //设置透明背景 self.backgroundColor = [UIColor clearColor]; } return self; }
线条 两个属性 起始点 结束点(这就是数学中的两点确定一条直线)
给Line 类创建两个属性
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface Line : NSObject @property(nonatomic)CGPoint begin; //线条开始点 @property(nonatomic)CGPoint end; //线条结束点 @end
// Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code //获取上下文 CGContextRef cgt=UIGraphicsGetCurrentContext(); //设置线条宽度 CGContextSetLineWidth(cgt, self.lineWidth); //设置线条两端形状为圆角 CGContextSetLineCap(cgt, kCGLineCapRound); //设置颜色 [self.lineColor set]; //绘制已经完成的线段 for (Line *line in _completeLines){ CGContextMoveToPoint(cgt, [line begin].x, [line begin].y); CGContextAddLineToPoint(cgt, [line end].x, [line end].y ); CGContextStrokePath(cgt); } //绘制正在画的线段 for (NSArray *v in _LinesInProscess) { Line *line =[_LinesInProscess objectForKey:v]; CGContextMoveToPoint(cgt, [line begin].x, [line begin].y); CGContextAddLineToPoint(cgt, [line end].x, [line end].y ); CGContextStrokePath(cgt); } }
//清空画板 -(void)clearAll { [_completeLines removeLastObject]; [_LinesInProscess removeAllObjects]; [self setNeedsDisplay]; } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //判断是否连按 for (UITouch *t in touches) { if ([t tapCount]>1) { //第二次画线时第一条线还未完成时结束画线 [self clearAll]; return; } //NSValue 作为键使用 NSValue *key=[NSValue valueWithNonretainedObject:t]; // 根据触摸位置创建Line对象 CGPoint loc=[t locationInView:self]; Line *newLine=[[Line alloc]init ]; newLine.begin=loc; newLine.end=loc; //将当前正在画的线存入字典 [_LinesInProscess setObject:newLine forKey:key]; } } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { //手指移动过程中按照当前手指的位置动态更新线条 for (UITouch * t in touches) { NSValue *key=[NSValue valueWithNonretainedObject:t]; // 找对象当前UITouch对象的Line对象 Line *line =[_LinesInProscess objectForKey:key]; CGPoint loc=[t locationInView:self]; line.end=loc; } [self setNeedsDisplay]; } -(void)endTouches:(NSSet *) touches { //画线完成之后将当前线条加入_completeLines 数组中 同时删除字典_LinesInProscess里的线条 for (UITouch *t in touches) { NSValue *key=[NSValue valueWithNonretainedObject:t]; Line *line =[_LinesInProscess objectForKey:key]; if (line) { [_completeLines addObject:line]; [_LinesInProscess removeObjectForKey:key]; } } [self setNeedsDisplay]; } -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self endTouches:touches]; } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self endTouches:touches]; }
回到 ViewController中 给按钮点击事件中 添加DrawLine到ImageView上
- (void)addLineAct:(id)sender{ NSLog(@"测试按钮"); DrawLine *touchdrawView = [[DrawLine alloc]initWithFrame:imageV.frame]; touchdrawView.lineColor = [UIColor yellowColor]; touchdrawView.lineWidth = 5.0; touchdrawView.tag = 902; [self.view addSubview:touchdrawView]; }
带剪头的线条
在上面例子的基础上稍微拓展一下,给线段末尾加上一个箭头
给DrawLine 类中添的方法 drawRect 中添加一段代码
//添加剪头 double r = sqrt((line.end.x-line.begin.x)*(line.end.x-line.begin.x)+(line.begin.y-line.end.y)*(line.begin.y-line.end.y));//线条长度 CGContextMoveToPoint(cgt,line.end.x,line.end.y); //P1 CGContextAddLineToPoint(cgt,line.end.x-(10*(line.begin.y-line.end.y)/r),line.end.y-(10*(line.end.x-line.begin.x)/r)); //P3 CGContextAddLineToPoint(cgt,line.end.x+(20*(line.end.x-line.begin.x)/r), line.end.y-(20*(line.begin.y-line.end.y)/r)); //P2 CGContextAddLineToPoint(cgt,line.end.x+(10*(line.begin.y-line.end.y)/r),line.end.y+(10*(line.end.x-line.begin.x)/r)); CGContextAddLineToPoint(cgt, line.end.x,line.end.y); CGContextDrawPath(cgt,kCGPathFillStroke); CGContextStrokePath(cgt);
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。