Swift — 畫個圖案吧( CAShapeLayer )

Jeremy Xue
7 min readJun 8, 2018

--

CAShapeLayer

A layer that draws a cubic Bezier spline in its coordinate space.

蘋果官方文件內的說法實在是有點艱深,令人有點難以理解,於是我找到了一個更好的網站來說明這一切:

其中的重點大概就是:

  • CAShapeLAyer 可以被觸碰和填充,並且他們的線條屬性可以被進行調節。
  • CAShapeLAyer 還具有許多動畫的特性,這使開發人員人員可以創建吸引人的動畫效果。
  • 最重要的是 CAShapeLayer 在完全的在 GPU 上渲染,使其非常快速。

因為 CAShapeLayer 是一個向量繪製圖層,我們不需要擔心有關其 contentScale 屬性。無論他的值為多少,CAShapeLayer 都將以設備的主要螢幕比例繪製。

CAShaperLayer 的路徑(Path)是成為其形狀的重點核心,也就是說繪製什麼樣子,形狀就是繪出的那個樣子。路徑屬性為 CGPath,因此他使用與 CoreGraphics 相同的路徑邏輯,或者可以使用常常與 CAShapeLayer 配合的 UIBezierPath 來進行繪製圖形。

首先我們先來練習畫幾個常用的圖案:

正方形

let shapeLayer = CAShapeLayer()
shapeLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
shapeLayer.fillColor = UIColor.cyan.cgColor // 若想為透明可設為 nil
shapeLayer.lineWidth = 3 // 線條寬度
shapeLayer.strokeColor = UIColor.black.cgColor // 線條顏色
// 將我們的路徑設置跟我們 frame 一樣
// 最後將我們的 shapeLayer 路徑設置為 path
let path = UIBezierPath(rect: shapeLayer.frame)
shapeLayer.path = path.cgPath
shapeLayer.position = view.center // 讓圖層置中view.layer.addSublayer(shapeLayer)
使用 CAShapeLayer 繪製一個正方形

圓形

let shapeLayer = CAShapeLayer()shapeLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
shapeLayer.fillColor = UIColor.orange.cgColor
shapeLayer.lineWidth = 3
shapeLayer.strokeColor = UIColor.black.cgColor
let arcCenter:CGPoint = shapeLayer.position // 設定圓心let radius:CGFloat = 100 // 設定半徑// 剩下沒設置到的參數就為起始角度跟結束角度,最後為是否順時針
let path = UIBezierPath(arcCenter: arcCenter, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Float.pi), clockwise: true)
shapeLayer.path = path.cgPath
shapeLayer.position = view.center
view.layer.addSublayer(shapeLayer)
使用 CAShapeLayer 繪製一個圓形

使用新的方式繪製圖案

在 UIBezierPath 中還有一個 addline(to : CGPoint) 的方法,你可以想像他會由上一個點,到目前你 addline 的這個點的連線畫一條線,而對所包圍的範圍進行填充,下面我畫出一個缺少上邊的正方形:

let shapeLayer = CAShapeLayer()shapeLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
shapeLayer.fillColor = nil
shapeLayer.lineWidth = 3
shapeLayer.strokeColor = UIColor.black.cgColor
// 可以把 move 想像為起點,addline 則是下一個點的位置let path = UIBezierPath()
path.move(to: .zero)
path.addLine(to: CGPoint(x: 0, y: 200))
path.addLine(to: CGPoint(x: 200, y: 200))
path.addLine(to: CGPoint(x: 200, y: 0))
shapeLayer.path = path.cgPath
shapeLayer.position = view.center
view.layer.addSublayer(shapeLayer)
使用 addline 方式畫正方形邊線

現在我們為他上色,看會變成什麼樣子

shapeLayer.fillColor = UIColor.cyan.cgColor
填充後的的正方形

剛剛的畫圓方式我們畫一半也是如同這種效果,只需把 2 * .pi 設為 .pi:

填充後的半圓形

Hey,來個考題:如何畫出一個 1 / 4填充扇形

假如你的答案是把剛剛的 .pi 改為 .pi / 2 那麼就大錯特錯了,假如只單純更改這個值,畫出的圖案會像是這樣:

單純更改 pi / 2 畫出的圖形

是不是畫出一個奇怪的弓形,但是畫出這個圖之後應該也有一個方向,是不是少了哪個邊,我們缺少了一條 “ 連回中心的線 ” ,所以我們可以使用 addline 畫出一條連到中心的線:

let path = UIBezierPath(arcCenter: arcCenter, radius: radius, startAngle: 0, endAngle: CGFloat(Float.pi) / 2, clockwise: true)path.addLine(to: shapeLayer.position)
繪製一個 1/4 圓

這次的教程就先教到這邊,有更多的 CAShapeLayer 的教學,之後會慢慢補充。

--

--

Jeremy Xue
Jeremy Xue

Written by Jeremy Xue

Hi, I’m Jeremy. [好想工作室 — iOS Developer]

No responses yet