iosのアニメーション(拡大・縮小)

アニメーションつけたくて色々調べた。
スケーリングのアニメーションの仕方はキータに載ってなかったので。

結果的に、動いたコードは

//
//  ViewController.swift
//  PhaseProgress
//
//  Created by b1u3 on 2018/09/17.
//  Copyright © 2018年 b1u3. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    lazy private var innerCircle = InnerCircle(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    lazy private var outerCircle = OuterCircle(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    var reverse = false
    var isAnimating = false

    @IBAction func Tap(_ sender: UITapGestureRecognizer) {
        if isAnimating == false {
            isAnimating = true
            UIView.animate(withDuration: 1.0, delay: 0.0, options: [], animations: {
                if !self.reverse {
                    self.innerCircle.transform = self.innerCircle.transform.scaledBy(x: 0.01, y: 0.01)
                }else {
                    self.innerCircle.transform = self.innerCircle.transform.scaledBy(x: 100.0, y: 100.0)
                }
            }, completion: {
                [] arg in
                self.reverse = !self.reverse
                self.isAnimating = false
            })
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.innerCircle)
        self.view.addSubview(self.outerCircle)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.layoutRects()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    private func createBlueRect()->UIView{
        let rect = UIView(frame: CGRect.zero)
        rect.backgroundColor = UIColor.blue
        return rect
    }
    
    private func createRedCircle()->UIView{
        let rect = UIView(frame: CGRect(x: 10, y: 20, width: 100, height: 100))
        rect.alpha = 0.5
        rect.layer.cornerRadius = 50
        rect.backgroundColor = UIColor.red
        return rect
    }

    private func layoutRects(){
        self.innerCircle.center.x = self.view.center.x
        self.innerCircle.center.y = self.view.center.y
        self.outerCircle.center.x = self.view.center.x
        self.outerCircle.center.y = self.view.center.y
    }

}

class InnerCircle: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.isOpaque = false
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {
        let arc = UIBezierPath(arcCenter: CGPoint(x: rect.width/2, y: rect.height/2), radius: rect.width>rect.height ?rect.height/2*0.8 : rect.width/2*0.8, startAngle: 0, endAngle: 360, clockwise: true)
        UIColor.red.setFill()
        arc.fill()
    }
}

class OuterCircle: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.isOpaque = false
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {
        let arc = UIBezierPath(arcCenter: CGPoint(x: rect.width/2, y: rect.height/2), radius: rect.width > rect.height ? rect.height/2*0.8 : rect.width/2*0.8, startAngle: 0, endAngle: 360, clockwise: true)
        UIColor.red.setStroke()
        arc.lineWidth = 1
        arc.stroke()
    }

}

こんな感じになった。InnerCircleが拡大、縮小するアニメーション。調べたのはUIBezierPathとAffinTransform。
scaledByで0を指定するとバグる。durationが効かなくなるので注意する。

今日明日中に、InnerCircleとOuterCircleをまとめてViewにする予定。