はじめに
インジケータを自作する方法です。
標準で搭載されているものでも十分事足りるのですが、アプリの色を出したいときにインジケータの演出もこだわりたいですよね。
提供中のTIME HACKERにも自作のインジケータを導入した方ので、以下のキャプチャのようなものを自作しました。
今日は、その際のやりかたです。
パラパラ漫画のような作り方でも良いのですが、上記キャプチャを見てもらえばわかるように、一部だけエンドレスに回転させる程度なら、CGAffineTransformを利用します。
CGAffineTransform
CGAffineTransformは、UIViewの拡大・縮小・回転などを実装するのをサポートしています。
これを用いて、回転するUIViewを作ります。
class IndicatorView: UIView { @IBOutlet weak var indicatorPin: UIImageView! func start() { UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveLinear, animations: { self.indicatorPin.transform = CGAffineTransform(rotationAngle: CGFloat.pi) self.indicatorPin.transform = CGAffineTransform.identity }, completion: { completed in self.start(title: title) }) } }
indicatorPinに回転したい画像をセットし、startメソッド内の、UIView.animateメソッドを使って回転させます。
animationsの中身は、以下のように指定することで、1周分の回転を指定します。
self.indicatorPin.transform = CGAffineTransform(rotationAngle: CGFloat.pi) self.indicatorPin.transform = CGAffineTransform.identity
最後のcompletionで自分自身を再帰呼び出し、1周回ったら次の周へ・・・とエンドレスに呼び出しています。
また、途中で止めたい場合は、stop用のメソッドなどを作ると良いかもです。
完成形
上記含めて、自作Indicatorの簡単な完成形です。
outletのところは、xibと接続してください。
class IndicatorView: UIView { /// Indicatorの動作フラグです /// - true: Indicatorの動作を停止します /// - false: Indicatorの動作を開始します var finished = true @IBOutlet weak var indicatorPin: UIImageView! override init(frame: CGRect) { super.init(frame: frame) loadNib() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! loadNib() } /// Indicatorを開始します /// func start() { finished = false running() } /// Indicator animationを実行します func running() { if finished == true { return } UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveLinear, animations: { self.indicatorPin.transform = CGAffineTransform(rotationAngle: CGFloat.pi) self.indicatorPin.transform = CGAffineTransform.identity }, completion: { completed in self.running() }) } func stop() { finished = true } private func loadNib(){ let view = Bundle.main.loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)?.first as! UIView view.frame = self.bounds self.addSubview(view) } }
最後に、これを使いたいViewControllerのStoryboard等に設置して、以下のように呼び出すだけです。
{IndicatorViewのインスタンス}.start() {IndicatorViewのインスタンス}.stop()