一个画板demo(二)
上一篇已经完成了基本的页面布局,接下来要实现第一个功能:让画笔画上去,改变画笔颜色,以及改变画笔粗细。
在storyboard和xib中拖拽控件来布局界面,并且想要在界面上加点东西的话就要在awakefromnib方法里添加。
画板的效果是能够识别在屏幕上的触摸点来画线,因此要获得屏幕上的触摸点。
有两种方法,一种是在
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent
方法里面获取触摸点(大概这样子)
1 -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ 2 UITouch *touch = [touches anyObject]; 3 4 5 6 //判断是否第一次触摸 7 if (touch.phase == UITouchPhaseBegan) { 8 //获取第一次触摸点的坐标 9 CGPoint location = [touch locationInView:self]; 10 UIBezierPath *bpath = [UIBezierPath bezierPath]; 11 //将路线的起始点移到触摸开始点 12 [bpath moveToPoint:location]; 13 14 15 //将路线加到数组里面 16 [_bpathsArray addObject:bpath]; 17 } 18 }
着重讲另一种方法,这种方法应该简单一点
用UIPanGestureRecognizer添加拖动的手势
1 //添加拖动的手势 2 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)]; 3 [self addGestureRecognizer:pan];
在-(void)pan:(UIGestureRecognizer *)panGesture方法里面创建路线。
-----这里有一个稍后要改的,画线用的类是UIBezierPath,但是这个类里面并没有改变线条颜色的属性,因此会想到要自定义一个类,这个类继承于UIBezierPath,只不过是比他多了一个属性(设置方法也行,但是设置属性会默认提供set 和 get方法。
起一个浪漫的名字 ,在DrawView里面导入这个类的头文件。
在DrawView.h设置外部可以改变的属性值。
1 @interface DrawView : UIView 2 //添加对外可以设置的属性值 3 @property(nonatomic , assign)CGFloat lineWidth; 4 5 @property(nonatomic , strong)UIColor *lineColor; 6 7 @end
UIPanGestureRecognizer创建的对象有一个属性state,是枚举类型,可以判断点是刚触摸上去还是改变了。
1 @property(nonatomic,readonly) UIGestureRecognizerState state; // the current state of the gesture recognizer 2 3 4 5 typedef NS_ENUM(NSInteger, UIGestureRecognizerState) { 6 UIGestureRecognizerStatePossible, // the recognizer has not yet recognized its gesture, but may be evaluating touch events. this is the default state 7 8 UIGestureRecognizerStateBegan, // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop 9 UIGestureRecognizerStateChanged, // the recognizer has received touches recognized as a change to the gesture. the action method will be called at the next turn of the run loop 10 UIGestureRecognizerStateEnded, // the recognizer has received touches recognized as the end of the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible 11 UIGestureRecognizerStateCancelled, // the recognizer has received touches resulting in the cancellation of the gesture. the action method will be called at the next turn of the run loop. the recognizer will be reset to UIGestureRecognizerStatePossible 12 13 UIGestureRecognizerStateFailed, // the recognizer has received a touch sequence that can not be recognized as the gesture. the action method will not be called and the recognizer will be reset to UIGestureRecognizerStatePossible 14 15 // Discrete Gestures – gesture recognizers that recognize a discrete event but do not report changes (for example, a tap) do not transition through the Began and Changed states and can not fail or be cancelled 16 UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible 17 };
这里判断一下触摸点的状态,
1 //判断一下是否刚触摸上去 2 if (panGesture.state == UIGestureRecognizerStateBegan) { 3 //刚触摸上去 4 //将路线的起始点移到这个点 5 6 7 8 }else if (panGesture.state == UIGestureRecognizerStateChanged){ 9 10 11 12 }
当panGesture.state == UIGestureRecognizerStateBegan时,
这里要注意,当外部没有设置值的时候可能会报错,因此设置默认值。
1 if (panGesture.state == UIGestureRecognizerStateBegan) { 2 //刚触摸上去 3 //将路线的起始点移到这个点 4 ApprendreBezierPath *bpath = [ApprendreBezierPath bezierPath] ; 5 6 [bpath moveToPoint:location]; 7 8 //外部改变bpath的画笔颜色 和粗细 9 bpath.lineWidth = _lineWidth; 10 11 bpath.lineColor = _lineColor; 12 13 14 //将bpath添加到数组里 15 [_bpathsArray addObject:bpath]; 16 }
1 else if(panGesture.state == UIGestureRecognizerStateChanged){ 2 //拖动状态 3 //与上次的点形成一条线 4 //获取当前正在画的图形路径 5 //数组里面最后一个对象 6 ApprendreBezierPath *bpath = [_bpathArray lastObject]; 7 [bpath addLineToPoint:location]; 8 //刷新画板 9 [self setNeedsDisplay]; 10 11 }
在- (void)drawRect:(CGRect)rect里面画线
1 - (void)drawRect:(CGRect)rect { 2 // Drawing code 3 //取出数组里面所有的路线,连起来 4 for (ApprendreBezierPath *bpath in _bpathsArray) { 5 //设置颜色 虽然ApprendreBezierPath继承于UIBezierPath但是还是没有设置颜色的方法。 6 [bpath.lineColor set]; 7 8 [bpath stroke]; 9 10 } 11 }
接下来关联storyboard里面的控件
同样的方法
在viewcontroller.m导入头文件
现在能画上去了,但是注意到
箭头指向连接处 很尖锐,因此设置bpath的lineJoinStyle属性
原文地址:https://www.cnblogs.com/apprendre-10-28/p/10575591.html