iOS如何開發(fā)簡單的手繪應(yīng)用實(shí)例詳解
開發(fā)一款簡單的 iOS 手繪應(yīng)用,
收集點(diǎn),繪制形狀,給形狀著色,呈現(xiàn)給用戶,好像就完了
框架是 Quartz2D
1, 收集點(diǎn)
首先需要有一個(gè)界面 UIView, 用這個(gè)界面監(jiān)聽用戶的手勢,收集點(diǎn)
- 用戶按下手指
location(in, 從觸摸事件中,獲得在畫板中的坐標(biāo)
var lastPoint = CGPoint.zero override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return } // ... lastPoint = touch.location(in: view) }
- 用戶移動(dòng)手指
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { // ... }
- 用戶抬起手指
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { // ... }
2, 繪制形狀,給形狀著色
開辟一塊繪圖上下文 UIGraphicsGetCurrentContext,
使用采集的點(diǎn)連線
用戶手繪的不是一段連續(xù)的曲線,是很多個(gè)線段拼接起來的
func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) { UIGraphicsBeginImageContext(view.frame.size) guard let context = 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, 呈現(xiàn)給用戶
第一步使用的 UIView 是 UIImageView,
- 繪制就是畫一小段,取出畫好的圖片,賦給 UIImageView,我們就看到了
- 連續(xù)的繪制,是畫一小段,取出畫好的圖片,賦給 UIImageView,并用變量保存下最新的圖片
接著畫,先把剛才的圖片變量繪制一遍,再畫一小段,取出畫好的圖片,賦給 UIImageView,并用變量保存下最新的圖片
func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) { UIGraphicsBeginImageContext(view.frame.size) guard let context = UIGraphicsGetCurrentContext() else { return } tempImageView.image?.draw(in: view.bounds) // 繪制 ... tempImageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() }
4, 畫筆設(shè)置
修改畫筆顏色和粗細(xì)
func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) { UIGraphicsBeginImageContext(view.frame.size) guard let context = UIGraphicsGetCurrentContext() else { return } // ... context.setBlendMode(.normal) // 調(diào)顏色 context.setLineWidth(brushWidth) // 調(diào)粗細(xì) context.setStrokeColor(color.cgColor) // ... }
畫筆變橡皮擦
- 方法一,把畫筆的顏色,調(diào)成畫板的顏色,就成了橡皮擦
- 方法 2 ,
把畫筆的顏色,調(diào)成透明,
把繪圖上下文的混色模式改掉
就成了橡皮擦
switch type { case .pencil, .none: context.setBlendMode(.color) case .eraser: context.setLineWidth(15) context.setStrokeColor(UIColor.clear.cgColor) context.setBlendMode(.clear) }
5,后續(xù)
更多功能:
加入文本輸入功能,
需要一個(gè)文本框控件 UITextField、 UITextView
文本框控件一般可以拖動(dòng),
文本框放在畫布上,拖出畫布了,有些問題。
這時(shí)候要做一個(gè)邊界檢測
性能優(yōu)化:
一般性能優(yōu)化,就是打印函數(shù)的執(zhí)行時(shí)間
當(dāng)畫布的大小為 1366 X 7700 ( iPad Pro + UIScrollView ) 的時(shí)候,畫布很大,
全部繪制一遍,并取出圖片,性能消耗很大
tempImageView.image?.draw(in: view.bounds) // ... tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
繪制一次,需要約 0.07 秒,
let t = Date() self.drawingImage() if #available(iOS 13.0, *) { let span = t.distance(to: Date()) print(span) }
我們期望 60 的 FPS, 每一幀計(jì)算時(shí)間 0.016, 所以頻繁調(diào)用該方法,卡得厲害
之前的方法是一個(gè)點(diǎn),一個(gè)點(diǎn)的繪制
移動(dòng)一下,繪制一次
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return } swiped = true let currentPoint = touch.location(in: view) drawLine(from: lastPoint, to: currentPoint) lastPoint = currentPoint }
畫一段線, func touchesMoved() ,一般可以觸發(fā) 30 ~ 60 次,收集的點(diǎn)比較多,線條柔和
此時(shí)頻繁調(diào)用該消耗性能方法,
只能觸發(fā) 6 次,畫一段只能采集 6 個(gè)點(diǎn),正常手速,就畫出來一個(gè)多邊形
可以這樣優(yōu)化,點(diǎn)的收集與繪制分離
使用一個(gè) Timer ,每隔 0.15 秒,繪制一次
原本收集點(diǎn),是一個(gè) CGPoint, 現(xiàn)在收集點(diǎn),是一個(gè) [CGPoint]
- 原本畫一次之前的 image, 連一根線,更新圖片變量并呈現(xiàn)
n 個(gè)點(diǎn), 來 n 次全畫板繪制
- 現(xiàn)在畫一次之前的 image, 連接多根線,更新圖片變量并呈現(xiàn)
n 個(gè)點(diǎn), 來 1 次全畫板繪制
消耗性能的方法,少調(diào)用,就對了
tempImageView.image?.draw(in: view.bounds) // ... tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
后續(xù)需要整理,tbd
總結(jié)
到此這篇關(guān)于iOS如何開發(fā)簡單的手繪應(yīng)用的文章就介紹到這了,更多相關(guān)iOS開發(fā)手繪應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
iOS10通知框架UserNotification理解與應(yīng)用
在iOS10系統(tǒng)中,通知被整合進(jìn)了UserNotification框架,除了使通知的處理脫離了UIApplication,通知功能的相關(guān)開發(fā)更加結(jié)構(gòu)化與模塊化外,還新增開放了許多更加靈活的開發(fā)接口,現(xiàn)在,開發(fā)者可以為通知定義UI末班,添加媒體附件,需要的朋友可以參考下2016-09-09iOS Swift 值類型與引用類型使用區(qū)別基礎(chǔ)詳解
這篇文章主要為大家介紹了iOS Swift 值類型與引用類型使用區(qū)別基礎(chǔ)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07iOS開發(fā)中以application/json上傳文件實(shí)例詳解
在和sever后臺(tái)交互的過程中、有時(shí)候、他們需要我們iOS開發(fā)者以“application/json”形式上傳,具體實(shí)例代碼大家參考下本文2017-07-07touchesBegan: withEvent: 不執(zhí)行解決
這篇文章主要介紹了touchesBegan: withEvent: 不執(zhí)行解決的相關(guān)資料,需要的朋友可以參考下2016-12-12iOS自帶文本轉(zhuǎn)語音技術(shù)(TTS)的實(shí)現(xiàn)即語音播報(bào)的實(shí)踐
這篇文章主要介紹了iOS自帶文本轉(zhuǎn)語音技術(shù)(TTS)的實(shí)現(xiàn)即語音播報(bào)的實(shí)踐,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09iOS AVPlayer切換播放源實(shí)現(xiàn)連續(xù)播放和全屏切換的方法
這篇文章主要給大家介紹了關(guān)于iOS中AVPlayer切換播放源實(shí)現(xiàn)連續(xù)播放和全屏切換的方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-05-05iOS開發(fā)中使用UIScrollView實(shí)現(xiàn)無限循環(huán)的圖片瀏覽器
這篇文章主要介紹了iOS開發(fā)中使用UIScrollView實(shí)現(xiàn)無限循環(huán)的圖片瀏覽器的方法,感興趣的小伙伴們可以參考一下2016-03-03