[iOS][Swift] ボタンにマテリアルデザイン風のフィードバックをつける
今回はマテリアルデザイン風フィードバックをiOSで作りたいと思います。
マテリアルデザイン風フィードバック = 『画面をタップしたところから円形の影みたいなのを出すモーション』です。
文章で書いても分かり辛いので、まずは下記アニメーションを御覧ください。
Button|Google Material Design Guidelineより
↑ これです。(下ボタンの方)
UIButtonにマテリアルデザイン風のフィードバックをつける
今回はボタンに対して処理を入れたいと思います。
まずはUIButtonのカスタムクラスを作成します。今回はMaterialButton.swiftという名前のファイルを作成しました。
import UIKit class MaterialButton: UIButton { override func awakeFromNib() { super.awakeFromNib() } }
タップした場所の座標を取得する
まずはタップした場所の座標を取得出来るようにします。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { ... }
でタップの開始を取得します。
touches.first?.locationInView(self)
はCGPointを返します。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { super.touchesBegan(touches, withEvent: event) if let point = touches.first?.locationInView(self) { // ここに処理を書く } }
フィードバック用のViewをつくる
今度はフィードバックとして表示するViewを生成します。
tapEffectView
というUIViewを用意し、そこに円を書いています。
class MaterialButton: UIButton { private let tapEffectView = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1)) override func awakeFromNib() { super.awakeFromNib() setup() } private func setup() { // ボタン自体を角丸にする layer.cornerRadius = 4.0 layer.masksToBounds = true // 円を描画 let shapeLayer = CAShapeLayer() shapeLayer.fillColor = UIColor.grayColor().CGColor shapeLayer.path = UIBezierPath(ovalInRect: tapEffectView.bounds).CGPath tapEffectView.layer.addSublayer(shapeLayer) tapEffectView.hidden = true addSubview(tapEffectView) } }
hiddenをtrueにして見えないようにしてからaddSubview
します。
これでフィードバック用のViewの準備が出来ました。
タップ時のアニメーションをつける
上で作成したフィードバック用のViewをタップ時に表示させます。
タップした場所の座標を取得するで作成したtouchesBegan
に処理を追加します。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { super.touchesBegan(touches, withEvent: event) if let point = touches.first?.locationInView(self) { tapEffectView.frame.origin = point tapEffectView.alpha = 0.3 tapEffectView.hidden = false tapEffectView.transform = CGAffineTransformMakeScale(1.0, 1.0) UIView.animateWithDuration(0.5, animations: { self.tapEffectView.alpha = 0 self.tapEffectView.transform = CGAffineTransformMakeScale(200.0, 200.0) }) { finished in self.tapEffectView.hidden = true self.tapEffectView.transform = CGAffineTransformMakeScale(1.0, 1.0) } } }
tapEffectView.frame.origin = point
でタップした座標にエフェクト用のViewを移動させます。
そしてtapEffectViewに対してScaleのアニメーションを入れました。
(アニメーションは適宜修正してください)
ボタンの適用
作成したMaterialButtonクラスをStoryboard上のボタンに対して設定します。
結果
実行してみると以下のような感じになります。
まとめ
マテリアルデザインのモーションはiOSでも大変参考になると思います。
Androidの良い所を積極的に取り入れれば、より素敵なアプリになるのではないでしょうか。