iOS如何开发简单的手绘应用实例详解
开发一款简单的iOS手绘应用,
收集点,绘制形状,给形状着色,呈现给用户,好像就完了
框架是Quartz2D
1,收集点
首先需要有一个界面UIView,用这个界面监听用户的手势,收集点
- 用户按下手指
location(in,从触摸事件中,获得在画板中的坐标
varlastPoint=CGPoint.zero overridefunctouchesBegan(_touches:Set,withevent:UIEvent?){ guardlettouch=touches.firstelse{ return } //... lastPoint=touch.location(in:view) }
- 用户移动手指
overridefunctouchesMoved(_touches:Set,withevent:UIEvent?){ //... }
- 用户抬起手指
overridefunctouchesEnded(_touches:Set,withevent:UIEvent?){ //... }
2,绘制形状,给形状着色
开辟一块绘图上下文UIGraphicsGetCurrentContext,
使用采集的点连线
用户手绘的不是一段连续的曲线,是很多个线段拼接起来的
funcdrawLine(fromfromPoint:CGPoint,totoPoint:CGPoint){ UIGraphicsBeginImageContext(view.frame.size) guardletcontext=UIGraphicsGetCurrentContext()else{ return } //... //绘制 context.move(to:fromPoint) context.addLine(to:toPoint) context.setLineCap(.round) context.setBlendMode(.normal) context.setLineWidth(brushWidth) context.setStrokeColor(color.cgColor) context.strokePath() //... UIGraphicsEndImageContext() }
3,呈现给用户
第一步使用的UIView是UIImageView,
- 绘制就是画一小段,取出画好的图片,赋给UIImageView,我们就看到了
- 连续的绘制,是画一小段,取出画好的图片,赋给UIImageView,并用变量保存下最新的图片
接着画,先把刚才的图片变量绘制一遍,再画一小段,取出画好的图片,赋给UIImageView,并用变量保存下最新的图片
funcdrawLine(fromfromPoint:CGPoint,totoPoint:CGPoint){ UIGraphicsBeginImageContext(view.frame.size) guardletcontext=UIGraphicsGetCurrentContext()else{ return } tempImageView.image?.draw(in:view.bounds) //绘制... tempImageView.image=UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() }
4,画笔设置
修改画笔颜色和粗细
funcdrawLine(fromfromPoint:CGPoint,totoPoint:CGPoint){ UIGraphicsBeginImageContext(view.frame.size) guardletcontext=UIGraphicsGetCurrentContext()else{ return } //... context.setBlendMode(.normal) //调颜色 context.setLineWidth(brushWidth) //调粗细 context.setStrokeColor(color.cgColor) //... }
画笔变橡皮擦
- 方法一,把画笔的颜色,调成画板的颜色,就成了橡皮擦
- 方法2,
把画笔的颜色,调成透明,
把绘图上下文的混色模式改掉
就成了橡皮擦
switchtype{ case.pencil,.none: context.setBlendMode(.color) case.eraser: context.setLineWidth(15) context.setStrokeColor(UIColor.clear.cgColor) context.setBlendMode(.clear) }
5,后续
更多功能:
加入文本输入功能,
需要一个文本框控件UITextField、UITextView
文本框控件一般可以拖动,
文本框放在画布上,拖出画布了,有些问题。
这时候要做一个边界检测
性能优化:
一般性能优化,就是打印函数的执行时间
当画布的大小为1366X7700(iPadPro+UIScrollView)的时候,画布很大,
全部绘制一遍,并取出图片,性能消耗很大
tempImageView.image?.draw(in:view.bounds) //... tempImageView.image=UIGraphicsGetImageFromCurrentImageContext()
绘制一次,需要约0.07秒,
lett=Date() self.drawingImage() if#available(iOS13.0,*){ letspan=t.distance(to:Date()) print(span) }
我们期望60的FPS,每一帧计算时间0.016,所以频繁调用该方法,卡得厉害
之前的方法是一个点,一个点的绘制
移动一下,绘制一次
overridefunctouchesMoved(_touches:Set,withevent:UIEvent?){ guardlettouch=touches.firstelse{ return } swiped=true letcurrentPoint=touch.location(in:view) drawLine(from:lastPoint,to:currentPoint) lastPoint=currentPoint }
画一段线,functouchesMoved(),一般可以触发30~60次,收集的点比较多,线条柔和
此时频繁调用该消耗性能方法,
只能触发6次,画一段只能采集6个点,正常手速,就画出来一个多边形
可以这样优化,点的收集与绘制分离
使用一个Timer,每隔0.15秒,绘制一次
原本收集点,是一个CGPoint,现在收集点,是一个[CGPoint]
- 原本画一次之前的image,连一根线,更新图片变量并呈现
n个点,来n次全画板绘制
- 现在画一次之前的image,连接多根线,更新图片变量并呈现
n个点,来1次全画板绘制
消耗性能的方法,少调用,就对了
tempImageView.image?.draw(in:view.bounds) //... tempImageView.image=UIGraphicsGetImageFromCurrentImageContext()
前4点的代码,见github
后续需要整理,tbd
总结
到此这篇关于iOS如何开发简单的手绘应用的文章就介绍到这了,更多相关iOS开发手绘应用内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。