3D touchのボタンアクションを擬似的に表現したHapticButtonライブラリを試してみた(MITライセンス)


はじめに

3D touchでボタンを押した際のポップアップするアニメーションを擬似的に表現したHapticButtonを試してみました。アニメーションは以下ような感じになります。

github/HapticButtonから引用

検証環境

以下の環境を使用しています。

  • macOS Sierra Version 10.12.5
  • Xcode Version 8.3.3
  • iPhone7 iOS10.3.2

ライセンス・対応iOS/Swift Version

  • ライセンス
    • MIT
  • 対応iOS
    • iOS 10.0 and Swift 3.2 are required.

可能なこと

以下のことが可能です。

  • ラベルかイメージかを選択してボタンの生成(.label(text: String)もしくは.image(image: UIImage))
  • lightBlurViewおよびdarkBlurViewの追加(磨りガラスのような効果 動画の2番目と3番目のボタン)
  • タッチしている力が一定値を超えた場合に実行するメソッドの指定
    • メソッドの定義方法は以下3種類(複数のメソッドが定義されている場合はどれか一つが実行される。実行の優先順位はdelegate > closure > touchUpInsideアクション)
      • delegate
        • HapticButtonDelegateを使用し、pressed(sender: HapticButton)メソッドに記入
      • closure
        • .onPressプロパティにclosureを定義
      • addTaget
        • HapticButtonにaddTargetでtouchUpInsideのアクションメソッドとして定義
  • メソッドを実行する強さの指定(デフォルトは0.25  0.0 <= threshold <= 1.0)

具体例

label指定_blurなし_delegateでメソッド定義
class ViewController: UIViewController {
    @IBOutlet weak var button: HapticButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        button.mode = .label(text: "Hello! 👋")
        button.delegate = self
    }

extension ViewController: HapticButtonDelegate {
    func pressed(sender: HapticButton) {
        print("White button pressed.")
    }
}
image指定_lightBlur_addTagetでメソッド定義
class ViewController: UIViewController {
    @IBOutlet weak var blurButton: HapticButton!

    override func viewDidLoad() {
        blurButton.mode = .image(image: #imageLiteral(resourceName: "imageName"))
        blurButton.addBlurView(style: .light)
        blurButton.addTarget(self, action: #selector(blurButtonPressed(_:)), for: .touchUpInside)
    }

    func blurButtonPressed(_ sender: HapticButton) {
        print("Light blur button pressed.")
    }
}
label指定_darkBlur_closureでメソッド定義
class ViewController: UIViewController {
    @IBOutlet weak var darkBlurButton: HapticButton!

    override func viewDidLoad() {
        darkBlurButton.mode = .label(text: "Hello Blur!")
        darkBlurButton.textLabel.textColor = .white
        darkBlurButton.addBlurView(style: .dark)
        darkBlurButton.onPressed = {
            print("Dark blur button pressed.")
        }
    }
}

補足

  • UIImpactFeedbackGeneratorを使用したフィードバックが実装されているので、iPhone7、iPhone7 plusでは押した際のフィードバックを感じることが可能です。
  • ボタンの拡大・縮小はtouchesMoved(_ touches: Set<UITouch>, with event: UIEvent)から、touch.force / touch.maximumPossibleForceより変換するscaleを計算し、CGAffineTransformを使用して行なっているようです。

所感

非常に簡単にボタンに3D touchで押した際のような挙動を加えられるのでなかなか面白いのではないかと感じました。ただ、ボタンを押したあとの挙動を自然にするのは少し大変かもしれません。

参考文献

BalestraPatrick/HapticButton