iOS Task#21 | Swift UI — Drawing by UIBezierPath

AH
彼得潘的 Swift iOS / Flutter App 開發教室
6 min readDec 16, 2021

在這之前練習建立 Project 都是使用 Storyboard 的介面為主,那什麼是 SwiftUI 呢?

SwiftUI

Apple 在 2019 WWDC 發表了強大的 SwiftUI。
它和 UIKit 一樣是處理 UI 的 framework,但不再需要依賴 Storyboard,而是完全建構在程式碼上,且用更少的程式碼、更簡單的語法來完成更繁瑣的功能。

利用 SwiftUI 的 Path 繪圖會比 UIKit 的 UIBezierPath 來得容易,且方便瀏覽結果,所以本篇先稍微帶到 SwiftUI 如何用來做繪圖結果的預覽。

但由於業界目前使用還是以 Storyboard 為主,尚未完全轉移使用 SwiftUI,前期會仍以 Storyboard 為主要學習的 framework,所以這裡對 SwiftUI 不多做說明。

Step 1. Create Project in SwiftUI

Step 2. Paste following code into ContentView.swift

左側 Project Navigator 選到ContentView.swift,貼上以下程式碼,並按右上角 Resume

import SwiftUIstruct DrawView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()

return view
}

func updateUIView(_ uiView: UIView, context: Context) {
}

}struct ContentView: View {
var body: some View {
DrawView()
}
}struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

Step 3. Draw in func makeUIView()

貼完 Step 2 的程式碼後,會看到右側出現像模擬器的瀏覽畫面,等等我們要在紅色框起來的地方輸入繪圖的程式碼。

func makeUIView(context: Context) -> UIView{   let view = UIView()   ///這裡要輸入繪圖的程式碼///   return view
}

用 UIBezierPath 繪製路徑的程式碼有兩種,以一個直角三角形為例:

  • 第一種寫法:

第二種寫法:move & addLine 生成 CGPoint (更簡易)

Step 4. CAShapeLayer

這時候會發現就算按下右上角的 Resume 還是沒有顯示出剛剛畫的三角形,因為目前繪製的路徑還是虛擬的,需要 CAShapeLayer 才能讓它顯示畫面。

所以在剛剛打的程式碼後面再加上:

// 指定triangleLayer為一種形狀
let triangleLayer = CAShapeLayer()
// 再利用path.cgPath讀取CGPath型別的三角形路徑後存入triangleLayer.path
triangleLayer.path = path.cgPath

Step 5. Add CAShapeLayer to View

預覽畫面還是沒有出現圖形,因為畫面會顯示 View,所以一樣,要把我們剛剛做的 triangleLayer 疊到 View 之上,讓它顯示在最上面的圖層。

view.layer.addSublayer(triangleLayer)

Step 6. Fill Color 設定顏色

會發現繪圖出來的三角形是全黑,這是 CAShapeLayer 預設的。

來換個我最愛的土耳其藍吧!

// 填滿顏色triangleLayer.fillColor = CGColor(srgbRed: 0, green: 0.5, blue: 0.5, alpha: 1)

Step 7. StrokeColor 設定邊框

strokeColor : 邊框顏色

lineWidth : 邊框的寬度。

// 邊框顏色triangleLayer.strokeColor = CGColor(srgbRed: 0, green: 0.5, blue: 0.5, alpha: 0.3)// 邊框寬度triangleLayer.lineWidth = 5

如果想要只有邊框,中間顏色留白不填滿,可將 fillColor 設為clear color.

// 填滿顏色triangleLayer.fillColor = UIColor.clear.cgColor// 邊框顏色triangleLayer.strokeColor = CGColor(srgbRed: 0, green: 0.5, blue: 0.5, alpha: 0.3)// 邊框寬度triangleLayer.lineWidth = 5

第一個圖形完成了!

加入多個 Layer

接著可以試試看疊上很多個不同的圖形,只要在同樣的位置輸入下一組圖型的程式碼,包含指定的座標位置、顏色、邊框。

後面加入的圖形會在前一個圖形的上方,是 Super/Sub 繼承的概念。

func makeUIView(context: Context) -> UIView{let view = UIView()///這裡要輸入繪圖的程式碼///return view
}

--

--