iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 3
0

Drawing Animation

  • 通過 UIBezier 在  Layer 上畫一個 Chat 的圖案
  • 製作一個 Loading 畫面

DrawingAnimation + CustomLoadingView

Drawing Animation

https://ithelp.ithome.com.tw/upload/images/20171222/20107329WjmvMw5zAa.png

這裡放了一個名字叫 customCanvas 的 View 在畫面上,我們打算在這個 View 的 Layer 上畫圖。

UIBezierPath

https://ithelp.ithome.com.tw/upload/images/20171222/20107329p40MIwAqvR.png
這裡通過 UIBezierPath 來畫出上面這張圖,當然靠想像力來畫有點難度,可以借助 PaintCode 這樣的工具來幫忙。

    private var customPath: UIBezierPath {
        let bezier2Path = UIBezierPath()
        bezier2Path.move(to: CGPoint(x: 166.1, y: 48.28))
        bezier2Path.addCurve(to: CGPoint(x: 166.1, y: 131.72), controlPoint1: CGPoint(x: 199.3, y: 71.32), controlPoint2: CGPoint(x: 199.3, y: 108.68))
        bezier2Path.addCurve(to: CGPoint(x: 89.68, y: 147.91), controlPoint1: CGPoint(x: 145.34, y: 146.13), controlPoint2: CGPoint(x: 116.5, y: 151.53))
        bezier2Path.addCurve(to: CGPoint(x: 43.5, y: 169.5), controlPoint1: CGPoint(x: 71.56, y: 159.66), controlPoint2: CGPoint(x: 43.5, y: 169.5))
        bezier2Path.addCurve(to: CGPoint(x: 58.33, y: 138.86), controlPoint1: CGPoint(x: 43.5, y: 169.5), controlPoint2: CGPoint(x: 53.16, y: 153.11))
        bezier2Path.addCurve(to: CGPoint(x: 45.9, y: 131.72), controlPoint1: CGPoint(x: 53.95, y: 136.8), controlPoint2: CGPoint(x: 49.78, y: 134.42))
        bezier2Path.addCurve(to: CGPoint(x: 45.9, y: 48.28), controlPoint1: CGPoint(x: 12.7, y: 108.68), controlPoint2: CGPoint(x: 12.7, y: 71.32))
        bezier2Path.addCurve(to: CGPoint(x: 166.1, y: 48.28), controlPoint1: CGPoint(x: 79.09, y: 25.24), controlPoint2: CGPoint(x: 132.91, y: 25.24))
        bezier2Path.close()
        bezier2Path.lineWidth = 9
        bezier2Path.stroke()
        
        return bezier2Path
    }

然後定義 shapeLayer:CAShapeLayer 的基本參數,比如粗細、顏色、填充等等,其中 path 就是上圖的路徑。

    lazy var shapeLayer:CAShapeLayer = {
        let layer = CAShapeLayer()
        layer.path = customPath.cgPath
        layer.strokeColor = UIColor.yellow.cgColor
        layer.fillColor = UIColor.clear.cgColor
        layer.lineWidth = 4.0
        layer.lineCap = kCALineCapRound
        return layer
    }()

並將它加入到 customCanvas 當中

customCanvas.layer.addSublayer(shapeLayer)

customCanvas
當我們拖動 UiSlider 的時候,改變畫圖的進度

shapeLayer.strokeEnd = CGFloat(slider.value)

Custom Loading View

我們另外建了一個 LoadingViewController 用來顯示 Loading 的畫面。
https://ithelp.ithome.com.tw/upload/images/20171222/20107329coC6ftyXWe.png
這次要畫的圓的路徑就容易多了

    private var customPath: UIBezierPath {
        let bezierPath = UIBezierPath(ovalIn: CGRect(x: 35, y: 35, width: 75, height: 75))
        return bezierPath
    }

然後在加入到 shapeLayer 當中

    lazy var shapeLayer:CAShapeLayer = {
        let layer = CAShapeLayer()
        layer.path = customPath.cgPath
        layer.strokeColor = UIColor.blue.cgColor
        layer.fillColor = UIColor.clear.cgColor
        layer.lineWidth = 4.0
        layer.lineCap = kCALineCapRound
        return layer
    }()

這次多了自動去執行動畫的部分,通過 repeatCount 可以設定動畫執行的次數,這裡設定了無數次 Float.infinity

        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = 0.0
        animation.byValue = 1.0
        animation.duration = 1.5
        animation.fillMode = kCAFillModeForwards
        animation.isRemovedOnCompletion = false
        animation.repeatCount = Float.infinity
        
        shapeLayer.add(animation, forKey: "drawChatIconAnimation")

Present LoadingViewController

這裡把 ViewController 最底層的 View 設定了 backGroundColor = UIColor.clear
這樣搭配設定 modalPresentationStyle / modalTransitionStyle 可以實現 ViewController 半透明的效果。

在 HomeViewController 中, present LoadingViewController

        let VC = LoadingViewController()
        VC.modalPresentationStyle = .overFullScreen
        VC.modalTransitionStyle = .crossDissolve
        present(VC, animated: true, completion: nil)

筆記

思考:在使用 UIBezierPath 畫圖的時候,如何實現 autoLayout 而不是 hard code 方式給予數字。


參考


上一篇
StackViewAnimation
下一篇
Expandable Buttons - 折疊式按鈕
系列文
iOS Swift x Layout x Animation x Transition30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言