iOS如何開發(fā)簡單的手繪應用實例詳解
開發(fā)一款簡單的 iOS 手繪應用,
收集點,繪制形狀,給形狀著色,呈現(xiàn)給用戶,好像就完了
框架是 Quartz2D
1, 收集點
首先需要有一個界面 UIView, 用這個界面監(jiān)聽用戶的手勢,收集點
- 用戶按下手指
location(in, 從觸摸事件中,獲得在畫板中的坐標
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)
}
- 用戶移動手指
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
// ...
}
- 用戶抬起手指
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// ...
}
2, 繪制形狀,給形狀著色
開辟一塊繪圖上下文 UIGraphicsGetCurrentContext,
使用采集的點連線
用戶手繪的不是一段連續(xù)的曲線,是很多個線段拼接起來的
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è)置
修改畫筆顏色和粗細
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)粗細
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ù)
更多功能:
加入文本輸入功能,
需要一個文本框控件 UITextField、 UITextView
文本框控件一般可以拖動,
文本框放在畫布上,拖出畫布了,有些問題。
這時候要做一個邊界檢測
性能優(yōu)化:
一般性能優(yōu)化,就是打印函數(shù)的執(zhí)行時間
當畫布的大小為 1366 X 7700 ( iPad Pro + UIScrollView ) 的時候,畫布很大,
全部繪制一遍,并取出圖片,性能消耗很大
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, 每一幀計算時間 0.016, 所以頻繁調(diào)用該方法,卡得厲害
之前的方法是一個點,一個點的繪制
移動一下,繪制一次
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ào)用該消耗性能方法,
只能觸發(fā) 6 次,畫一段只能采集 6 個點,正常手速,就畫出來一個多邊形
可以這樣優(yōu)化,點的收集與繪制分離
使用一個 Timer ,每隔 0.15 秒,繪制一次
原本收集點,是一個 CGPoint, 現(xiàn)在收集點,是一個 [CGPoint]
- 原本畫一次之前的 image, 連一根線,更新圖片變量并呈現(xiàn)
n 個點, 來 n 次全畫板繪制
- 現(xiàn)在畫一次之前的 image, 連接多根線,更新圖片變量并呈現(xiàn)
n 個點, 來 1 次全畫板繪制
消耗性能的方法,少調(diào)用,就對了
tempImageView.image?.draw(in: view.bounds) // ... tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
后續(xù)需要整理,tbd
總結(jié)
到此這篇關(guān)于iOS如何開發(fā)簡單的手繪應用的文章就介紹到這了,更多相關(guān)iOS開發(fā)手繪應用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
兼容iOS 10 升級xcode8出現(xiàn)的問題及一些適配問題的解決方案
這篇文章主要介紹了兼容iOS 10 升級xcode8出現(xiàn)的問題及一些適配問題的解決方案,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09
iOS開發(fā)中UIImageView控件的常用操作整理
這篇文章主要介紹了iOS開發(fā)中UIImageView控件的常用操作整理,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-01-01
iOS開發(fā)中Quartz2D繪圖路徑的使用以及條紋效果的實現(xiàn)
這篇文章主要介紹了iOS開發(fā)中Quartz2D繪圖路徑的使用以及條紋效果的實現(xiàn),代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-11-11
iOS應用中UICollectionViewCell定制Button
這篇文章主要介紹了iOS應用中UICollectionViewCell如何定制Button,設(shè)置每行顯示的按鈕的個數(shù),自定制按鈕的顯示樣式,感興趣的小伙伴們可以參考一下2016-08-08

