一个画板demo

Posted apprendre-10-28

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个画板demo相关的知识,希望对你有一定的参考价值。

 一个画板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属性

 技术图片

 

技术图片 

 

以上是关于一个画板demo的主要内容,如果未能解决你的问题,请参考以下文章

canvas绘画板效果 html+css+js

canvas绘画板效果 html+css+js

Android绘画板(普通绘画模式和缩放平移绘画模式)

12mmaction2 行为识别商用级别X3D复现 demo实现 检测自己的视频 Expanding Architecturesfor Efficient Video Recognition(代码片段

如何使用STM32 HAL库驱动TFT-LCD实现手画板功能

[异常解决] Keil安装好nRF51822开发环境,运行DEMO报错:Error:“GPIOTE_CONFIG_NUM_OF_LOW_POWER_ENVENTS” is undefined(代码片段