贝塞尔曲线,听着挺牛气一词,不过下面我们在做画图板的时候就用到贝塞尔绘直线,没用到绘制曲线的功能。如果会点PS的小伙伴会对贝塞尔曲线有更直观的理解。这篇博文的重点不在于如何用使用贝塞尔曲线,而是利用贝塞尔划线的功能来封装一个画图板。

  画图板的截图如下,上面的白板就是我们的画图板,是自己封装好的一个UIView,下面会详细的介绍如何封装这个画图板,下面的控件用来控制我们画图板的属性以及Undo,Redo和保存功能。点击保存时会把绘制的图片保存到手机的相册中。下面是具体的实现方案。

  一.封装画图板

    其实上面的白板就是一继承于UiView的一个子类,我们可以在这个子类中添加我们画图板相应的属性和方法,然后实例化成对象添加到ViewController中,当然为了省事添加白板的时候是通过storyboard来完成的,读者也可以自己实例化然后手动的添加到相应的ViewController中。

    1.封装白板的第一步是新建一个UIView的子类MyView,然后添加相应的属性和方法。MyView.h中的代码如下,代码具体意思请参照注释

 #import <UIKit/UIKit.h>

 @interface MyView : UIView
//用来设置线条的颜色
@property (nonatomic, strong) UIColor *color;
//用来设置线条的宽度
@property (nonatomic, assign) CGFloat lineWidth;
//用来记录已有线条
@property (nonatomic, strong) NSMutableArray *allLine; //初始化相关参数
-(void)initMyView;
//unDo操作
-(void)backImage;
//reDo操作
-(void)forwardImage; @end

    2、上面的代码是对外的接口,有些属性我们是写在MyView.m的延展中以实现私有的目的,MyView延展部分如下:

 @interface MyView()
//声明贝塞尔曲线
@property(nonatomic, strong) UIBezierPath *bezier;
//存储Undo出来的线条
@property(nonatomic, strong) NSMutableArray *cancleArray;
@end

    3.下面的代码就是实现部分的代码了,会根据不同功能给出相应的说明

      (1).初始化我们的白板,给线条指定默认颜色和宽度并且给相应的变量分配内存空间,初始化代码如下:

 //进行一些初始化工作
-(void)initMyView
{
self.color = [UIColor redColor];
self.lineWidth = ;
self.allLine = [NSMutableArray arrayWithCapacity:];
self.cancleArray = [NSMutableArray arrayWithCapacity:];
}

  

      (2)Undo功能的封装,相当于两个栈,把显示的线条出栈,进入为不显示的线条栈中,每执行一次此操作显示线条栈中的元素会少一条而不显示线条栈中会多一条,大致就这个意思吧,代码如下:

 //UnDo操作
-(void)backImage
{
if (self.allLine.count > )
{
int index = self.allLine.count - ; [self.cancleArray addObject:self.allLine[index]]; [self.allLine removeObjectAtIndex:index]; [self setNeedsDisplay
];
}
}

    

      (3)Redo操作和Undo操作相反,从未显示栈中取出元素放入显示的栈中,代码中的栈我们是用数组来表示的,代码如下:

//ReDo操作
-(void)forwardImage
{
if (self.cancleArray.count > )
{
int index = self.cancleArray.count - ; [self.allLine addObject:self.cancleArray[index]]; [self.cancleArray removeObjectAtIndex:index]; [self setNeedsDisplay];
}
}

      (4)、当开始触摸时我们新建一个BezierPath,把触摸起点设置成BezierPath的起点,并把将要画出的线条以及线条对应的属性封装成字典添加到显示栈中,代码如下

 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//新建贝塞斯曲线
self.bezier = [UIBezierPath bezierPath]; //获取触摸的点
UITouch *myTouche = [touches anyObject];
CGPoint point = [myTouche locationInView:self]; //把刚触摸的点设置为bezier的起点
[self.bezier moveToPoint:point]; //把每条线存入字典中
NSMutableDictionary *tempDic = [[NSMutableDictionary alloc] initWithCapacity:];
[tempDic setObject:self.color forKey:@"color"];
[tempDic setObject:[NSNumber numberWithFloat:self.lineWidth] forKey:@"lineWidth"];
[tempDic setObject:self.bezier forKey:@"line"]; //把线加入数组中
[self.allLine addObject:tempDic]; }

      (5)当移动也就是划线的时候把点存储到BezierPath中,代码如下

 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouche = [touches anyObject];
CGPoint point = [myTouche locationInView:self]; [self.bezier addLineToPoint:point]; //重绘界面
[self setNeedsDisplay]; }

      (6)画出线条

 // Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
//对之前的线的一个重绘过程
for (int i = ; i < self.allLine.count; i ++)
{
NSDictionary *tempDic = self.allLine[i];
UIColor *color = tempDic[@"color"];
CGFloat width = [tempDic[@"lineWidth"] floatValue];
UIBezierPath *path = tempDic[@"line"]; [color setStroke];
[path setLineWidth:width];
[path stroke];
} }

  二.画图板的使用

    上面是封装画图板要用到的全部代码,下面的代码就是如何在ViewController中使用我们的画图板了,如何实例化控件,以及控件的初始化,注册回调等在这就不做赘述了,下面给出了主要控件的回调方法

    1、通过Slider来调节线条的宽度

 //通过slider来设置线条的宽度
- (IBAction)sliderChange:(id)sender
{
self.myView.lineWidth = self.mySlider.value;
}

  

    2、通过SegmentControl来设置线条的颜色

 /通过segmentControl来设置线条的颜色
- (IBAction)tapSegment:(id)sender { switch (self.mySegment.selectedSegmentIndex) {
case :
self.myView.color = [UIColor redColor];
break;
case :
self.myView.color = [UIColor blackColor];
break;
case :
self.myView.color = [UIColor greenColor];
break; default:
break;
} }

    3、undo和redo操作

 //Undo
- (IBAction)tapBack:(id)sender {
[self.myView backImage];
} //Redo操作
- (IBAction)tapGo:(id)sender {
[self.myView forwardImage];
}

    4.保存操作,也许下面的保存操作在处理方式上略显笨拙,如有更好的解决方案请留言。 保存的时候我是先截了个屏,然后把白板进行切割,把切割后图片存入到相册中,代码如下:

 //把画的图保存到相册
- (IBAction)tapSave:(id)sender {
//截屏
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *uiImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); //截取画图版部分
CGImageRef sourceImageRef = [uiImage CGImage];
CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, CGRectMake(, , , ));
UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; //把截的屏保存到相册
UIImageWriteToSavedPhotosAlbum(newImage , nil, nil, nil); //给个保存成功的反馈
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"存储照片成功"
message:@"您已将照片存储于图片库中,打开照片程序即可查看。"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show]; }

  以上就是本画图板的主要代码了,有不足之处还望批评指正。转载请注明出处。在本文结束时在来几张截图吧(demo下载地址:http://www.pgyer.com/LTQ8):

iOS开发之画图板(贝塞尔曲线)的更多相关文章

  1. IOS开发之画图形

    1 画线 2 画线第二个方法  相对方法1简洁 3 矩形 4 圆 5 弧线 6画文字(略) 7 画图片(略)

  2. 我的iOS开发系列博文

    之前目录性的总结了发表过的关于OC方面的文章,今天在目录性的总结一下有关iOS开发的文章.走过路过不要错过哦,今天的博文也全都是干货.写技术博客与大家交流一下思想也是不错的. 下面是我的技术博客中有关 ...

  3. Android 贝塞尔曲线 折线图

    1.贝塞尔曲线:http://baike.baidu.com/view/60154.htm,在这里理解什么是贝塞尔曲线 2.直接上图: 3.100多行代码就可以画出贝塞尔曲线,直接上代码 packag ...

  4. iOS开发 贝塞尔曲线

    iOS开发 贝塞尔曲线UIBezierPath - 陌云 时间 2014-03-14 11:04:00  博客园-所有随笔区 原文  http://www.cnblogs.com/moyunmo/p/ ...

  5. iOS开发 贝塞尔曲线UIBezierPath

    最近项目中需要用到用贝塞尔曲线去绘制路径 ,然后往路径里面填充图片,找到这篇文章挺好,记录下来 自己学习! 转至 http://blog.csdn.net/guo_hongjun1611/articl ...

  6. IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

    ... 首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Con ...

  7. (转) IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

    首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ...

  8. [置顶] IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

    首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ...

  9. iOS开发 贝塞尔曲线UIBezierPath(2)

    使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形 . 1:UIBezierPath: UIBezierPath是在 UIKit 中 ...

随机推荐

  1. Jsonp原理就是这么简单

    原理就是:包裹数据的js数据文件,自动执行,找到目标函数,通过传参,把数据注入进去. 当你打开本篇博文,证明你已经大体知道了Jsonp的作用了. 但如果需要我介绍一下,我也可以简单介绍: 简单说,就是 ...

  2. 在linux下Java的环境配置

    最近开始学习Java语言. 对于我这种初学者来说,一开始,我想先体验,大致看了一下Java语言是什么,如何实现... 然并卵o_O,表示看得很迷糊.还是实践最重要,把环境配置好再开始深入学习. 1.首 ...

  3. webstorm2016注册码

    43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...

  4. [ios]新手笔记-。-UIPickerView 关于伪造循环效果和延时滚动效果

    查找了网上资料,循环效果绝大部分都是增加行数来制造循环的错觉,延时滚动就是利用NSTimer间隔出发滚动事件来制造滚动效果. 代码: #import <UIKit/UIKit.h>#imp ...

  5. input在标签内设置禁止输入空格

    1.通过正则匹配解决问题 此处涉及\s:匹配任意空白符  \S:匹配任意非空白字符 <input type="text" onkeyup="this.value=t ...

  6. Mybatis generator的使用

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...

  7. java的poi技术读取和导入Excel

    项目结构: http://www.cnblogs.com/hongten/gallery/image/111987.html  用到的Excel文件: http://www.cnblogs.com/h ...

  8. myeclipse导入项目出现jquery错误(有红叉)

    今天导入了一个项目,但是进去之后jquery出现了红叉,如图(事实上在我没调好之前两个jquery文件都有叉号) 怎么调呢?右键jquery文件,选择MyEclipse->Exclude Fro ...

  9. spring的代理模式

    静态代理: 首先定义一个接口,随便写一个方法 定义2个实现接口的方法 (被代理的对象) (代理对象) 需要将接口 定义get set 方法 代理增强的方法 然后实现 输出结果如下: 动态代理(jdk动 ...

  10. 《.NET之美》消息及勘误

    <.NET之美>消息及勘误 编辑最终还是采用了<.NET之美>作为书名,尽管我一直觉得这个名字有点文艺了,而更倾向于使用<.NET专题解析>这个名称. 目前已经可以 ...