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

原文地址:https://www.cnblogs.com/apprendre-10-28/p/10575591.html

时间: 2024-10-24 04:39:11

一个画板demo(二)的相关文章

ArcGIS API for JavaScript开发环境搭建及第一个实例demo

原文:ArcGIS API for JavaScript开发环境搭建及第一个实例demo ESRI公司截止到目前已经发布了最新的ArcGIS Server for JavaScript API v3.9,它提供了更为丰富而又强大的功能.     一.安装前准备 1.ArcGIS Server for JavaScript API各版本下载地址:http://support.esrichina-bj.cn/2011/0223/960.html,我们选择下载最新的"ArcGIS API for Ja

Autofac 一个使用Demo

一:接口 二:实现: 三:调用: 首先上图: 一:接口代码 public interface IPersonDa { PersonEntity Get(int id); } 二:实现 public class PersonDa : IPersonDa { public PersonEntity Get(int id) { using (BaseMgr.BaseSysDbContext db = new BaseSysDbContext()) { var result = db.People.Wh

jQuery 中 ajax 请求数据应用的一个小demo

举一个jquery中ajax的应用小 demo 便于以后的更多项目拓展 ,这里要注意的是保存的文件名和文件图片路径问题 ... ajax01.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> ajax小例子 </title> </head> <body> <!--

模仿京东顶部搜索条效果制作的一个小demo

最近模仿京东顶部搜索条效果制作的一个小demo,特贴到这里,今后如果有用到可以参考一下,代码如下 1 #define kScreenWidth [UIScreen mainScreen].bounds.size.width 2 #define kScreenHeight [UIScreen mainScreen].bounds.size.height 3 4 #import "mainViewController.h" 5 6 @interface mainViewController

这是关于FastJson的一个使用Demo,在Java环境下验证的

1 public class User { 2 private int id; 3 private String name; 4 public int getId() { 5 return id; 6 } 7 public void setId(int id) { 8 this.id = id; 9 } 10 public String getName() { 11 return name; 12 } 13 public void setName(String name) { 14 this.n

求一个整数的二进制中1的个数

题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 假设该整数为i.首先i和1做与运算,判断i的最低位是不是为1.接着把1左移一位得到2,再和i做与运算,就能判断i的次高位是不是1……这样反复左移,每次都能判断i的其中一位是不是1.基于此,我们得到如下代码 int NumberOf1_Solution(int i) { int count = 0; unsigned int flag = 1; while(flag) { if(

javascript 跟随鼠标移动的提示框的一个小demo

下面提供一种跟随鼠标移动的提示框的思路,方便在以后工作中应用,主要是应用到鼠标移动产生的数值来进行移动提示框的定位... CSS代码   .box{height:100px;width:100px;background:orange;position:relative;margin:40px;} .move{height:20px;width:20px;background:red;position:absolute;left:0px;top:0px;display:none;} HTML代码

jQuery 中 ajax 提交数据应用的一个小demo

举一个jquery中ajax的应用小 demo 便于以后的更多项目拓展 ,这里要注意的是保存的文件名问题 ... ajax02.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="form&qu

Highcharts+Ajax+Json+Sturts2实现的图形异步实时刷新的一个简单demo

原文:Highcharts+Ajax+Json+Sturts2实现的图形异步实时刷新的一个简单demo 源代码下载地址:http://www.zuidaima.com/share/1550463370480640.htm 此功能可以用在后端对数据的实时抓取,前端动态更新时使用,可以根据数据的变化进行实时刷新,基于之前我上传的一个图形demo改制.如有意见建议,疑问,大家可以留言一起探讨. 源代码截图: