#3 運用 UIBezierPath 繪製可愛圖案,比方雪人,米奇 & 可愛動物
Published in
5 min readMar 18, 2023
這邊使用SwiftUI 的繪圖path來做練習並記錄一些重點
快速鍵 cmd + option + p 強迫 SwiftUI 更新預覽畫面。
首先嘗試繪製簡單的三角形
第一件事情要記得手機的座標是從左上角開始
UIBezierPath移動繪製的路徑儲存下來
struct DrawView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()
// path 這邊只是先把我們想要移動繪製的路徑儲存下來,到這邊並不會執行繪圖
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 100, y: 0))
path.addLine(to: CGPoint(x: 100, y: 100))
path.close() // 從最後的一個點畫回起始點
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
}
CAShapeLayer
用
CGPath
來定義想要繪製的圖形,最後CAShapeLayer
就自動渲染出來
layer.addSublayer
把 CAShapeLayer() 加入到view.layer ,但要記得把UIBezierPath 轉型成CGpath
struct DrawView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 100, y: 0))
path.addLine(to: CGPoint(x: 100, y: 100))
path.close()
let triangleLayer = CAShapeLayer()
triangleLayer.path = path.cgPath
view.layer.addSublayer(triangleLayer)
// layer是在view上面的一層東西,所以這邊在layer上面再加一層圖層並繪製
// 接著返回一整個view
return view
}
CAShapeLayer 繪製形狀內的顏色
triangleLayer.fillColor = CGColor(srgbRed: 0, green: 0, blue: 1, alpha: 1)
// alpha 是透明度
triangleLayer.fillColor = UIColor.clear.cgColor
// 直接清除顏色
客製化線條
triangleLayer.strokeColor = CGColor(srgbRed: 0, green: 0, blue: 1, alpha: 1)
triangleLayer.lineWidth = 10
以上是手動繪圖的部分,接著開始進階方法
Convert SVG path to the UIBezierPath
- 把SVG下載下來用sublime打開
- 找到下圖的path,複製起來丟到這個網站去解析http://svg-converter.kyome.io/
- 解析出來的內容放進程式碼
但是到這邊會發現一個問題,不同尺寸大小的圖片會造成跑圖
解決方法:path.close() 後面使用下面程式碼去移動縮放圖面的大小位置
path.apply(CGAffineTransform.identity.scaledBy(x: 0.7, y:0.7).translatedBy(x: -90, y: 0))
但這個方式無法從根本解決擺放的位置與大小會很容易破圖。
進階++
請參考另一篇文章
結論:
花這麼多篇幅研究這個主題,主要是因為開發時可能顧及到太多圖檔都儲存在APP裡會造成容量肥大,其中之一的解決方法就是由APP來繪製圖案或自製按鈕來符合專案需求。
問題:
UIBezierPath 與 cgPath的差別
UIBezierPath要型成cgPath給CAShapeLayer()使用那為何不一開始就用cgPath