放肆的使用 UIBezierPath 和 CAShapeLayer 畫各種圖形

發表於2016-12-31

CAShapeLayer 是 CALayer 的子類,但是比 CALayer 更靈活,可以畫出各種圖形,當然,你也可以使用其他方式來畫,隨你。

雜談

在 CAShapeLayer 中,也可以像 CALayer 一樣指定它的 frame 來畫,就像這樣:

然後你就會得到如圖這樣的黑色矩形

11120336-cabed9c2ad73957b

但是,CAShapeLayer 有一個神奇的屬性 path 用這個屬性配合上 UIBezierPath 這個類就可以達到超神的效果。

UIBezierPath 顧名思義,這是用貝塞爾曲線的方式來構建一段弧線,你可以用任意條弧線來組成你想要的形狀,比如,你想用它來和上面一樣畫一個矩形,那就可以這樣子來做:

要注意的是,這裡就不要用backgroundColor 這個屬性了,而要使用 fillColorstrokeColor ,前者代表設定這個 Layer 的填充色,後者代表設定它的邊框色

可以試一下把上面程式碼設定顏色的部分改成這個樣子,那麼執行程式的時候就會是這種樣子

12120336-c62af1131985de8c

玩一下UIBezierPath

在說回 UIBezierPath ,在 UIBezierPath 的 init 方法中,就有很多方便你畫各種圖形的方法,比如你可以畫一個帶圓角的圖形

13120336-9823776fce62dd7e

還可以指定起始角和半徑畫圓

14120336-0d0087ee3b02abc4

在這裡涉及到角度的問題,起始角和結束角,這裡的角度使使用弧度制來表示,這裡我收藏了一張圖片,以方便參考

15120336-7f77dcb0cc28e0ef

怎麼畫曲線

貝塞爾曲線的畫法是由起點、終點、控制點三個引數來畫的,為了解釋清楚這個點,我寫了幾行程式碼來解釋它

我很隨意的定義了三個點,為了清楚顯示它們的位置,我放了三個矩形在上面以便觀察,然後呼叫 path.moveToPoint(startPoint) 讓它移動到起始點,然後呼叫path.addQuadCurveToPoint(endPoint, controlPoint: controlPoint) 這個方法告訴它結束點和控制點,這樣它就能畫出一條有弧度的線條了,如果把fillColor設定一個顏色,那麼它就會變成一個很醜的形狀了,示例圖如下

16120336-0d292e7a1fab289b

控制點決定了它的曲率,曲線的頂點不等於控制點的位置,具體可以看一下貝塞爾曲線的定義,你還可以使用兩個控制點來畫,兩個控制點可以使用方法 path.addCurveToPoint(endPoint, controlPoint1: controlPoint, controlPoint2: controlPoint2)來搞定

這樣它會是這個樣子

17120336-f19bd76f1caa0c35

再來說說 CAShapeLayer

CAShapeLayer 是個神奇的東西,給它一個path它就能變成你想要的形狀,它還有很多可以玩的地方。綜合使用可以組合成不同的動畫,比如下面這樣

18120336-8290d12457b8f5ea
demo1.gif
19120336-7e70eca941c957c4
demo2.gif
20120336-1899225022c2b637
demo3.gif

這三個動畫就是使用了 strokeEnd strokeStart lineWidth 三個屬性,第一個動畫用了strokeEnd這個屬性的值範圍是0-1,動畫顯示了從0到1之間每一個值對這條曲線的影響,strokeStart的方法則是相反的,如果把這兩個值首先都設定成0.5然後慢慢改變成0和1的時候就會變成第二個動畫,配合lineWidth則曲線會慢慢變粗,這裡的很多屬性都是支援動畫的。

示例程式碼

應用一下

前一陣子在仿時光網這個APP,其中有一個Layer的形狀很怪異,是這樣的

21120336-7b526aaef0bbdc19

很明顯它可以用 CAShapeLayer + UIBezierPath 來做,思路大概是這樣,先移動到左上方的位置,然後向下劃線,然後往右劃線,然後往上劃線,還剩一個蓋子,這個蓋子就用一個控制點控制曲率,非常簡單,程式碼如下

就能畫出這樣的形狀來

22120336-06410bfad53fb73e

再來一個複雜點的,微信下拉拍小視訊的那隻眼睛很有趣,來模仿一下那個效果吧,它是這樣的

23120336-3c41264e40f49e68

首先你得畫出這隻眼睛,這是眼睛包括5個部分組成(這個是用OC寫的)

然後,還是通過 UIBezierPath 和 CAShapeLayer 這樣的老套路來畫,程式碼較多

然後更改一下某些屬性的值,方便稍後的動畫

最後根據 UIScrollView 的 contentOffset 來控制各種屬性,辦法較笨,但管用。

最後

總之使用 UIbezierPath 和 CAShapeLayer 可以畫出你想要的任何形狀,沒有它做不到,只有你想不到,搞定了它們你就可以輕鬆定製你想要的任何控制元件了。

微信Demo

程式碼

https://github.com/J0HDev/WXVideo

相關文章