はじめに
iPhoneの中にはTaptic Engineという装置が搭載されている機種があります。これは、ホームボタンが物理ボタンでなくなった代わりに押した感触を発生させる装置です。ホームボタン以外にも何かを長押しした時や支払いが完了した時などにクリック感が発生します。
このTaptic EngineをPytoというアプリを用いて操作してみました。
環境
iPhone SE (2020)(iOS13.4.1)
Pyto(11.9)
Taptic EngineとHaptic Feedback
私はTaptic Engineがクリック感を発生させる装置、そのクリック感をHaptic Feedback(触覚フィードバック)と理解しています。
Haptic Feedbackの種類
iPhoneのHaptic Feedbackには3つの種類があります。こちら[1]のサイトを参考にしました。こちら[2]のサイトにも詳しく書いてあります。
種類 | 機能 |
---|---|
UIImpactFeedbackGenerator | 1回反応する。3段階の強さが選べる |
UISelectionFeedbackGenerator | 選択系のUI用。一番弱い反応 |
UINotificationFeedbackGenerator | 成功失敗等の通知用。3つの種類がある |
Pytoでの書き方
PytoではUIKit
が使えます。これはPythonistaでいうobjc_util
のような感じで、Objective-Cを触ることのできる機能です。実際はrubicon-objc
というライブラリであり、これを使ってObjective-Cを操作しているみたいです。PytoのUIKitのソースコード
prepare()
は呼び出す前に入れると遅延を最小にすることができるそうですが、オプションです。私が試した感じでは、入れても入れなくても違いは分かりませんでした。prepareのドキュメント
UIImpactFeedbackGenerator
3段階で強さを調整できます。0が最も弱いです。
import UIKit
generator = UIKit.UIImpactFeedbackGenerator.alloc().init()
generator.prepare()
power = 0 # 0~2の3段階
generator.initWithStyle(power) # 強さを設定
generator.impactOccurred() # 発動
UISelectionFeedbackGenerator
強さ調整はできません。
import UIKit
generator = UIKit.UISelectionFeedbackGenerator.alloc().init()
generator.prepare()
generator.selectionChanged() # 発動
UINotificationFeedbackGenerator
3種類の反応を選べます。Success(トントン)=0, Warning(トントン)=1, Error(トコトン)=2です。
import UIKit
generator = UIKit.UINotificationFeedbackGenerator.alloc().init()
generator.prepare()
mode = 0 # 0~2の3種。
generator.notificationOccurred(mode) # 発動
3つを一度に試すプログラム
上記3種、すべての強さを一度に試すコードです。
import UIKit
import time
generator = UIKit.UIImpactFeedbackGenerator.alloc().init()
generator2 = UIKit.UISelectionFeedbackGenerator.alloc().init()
generator3 = UIKit.UINotificationFeedbackGenerator.alloc().init()
print("impact start")
generator.prepare()
for i in range(3):
print(f"-{i}")
for j in range(3):
generator.initWithStyle(i)
generator.impactOccurred()
time.sleep(0.3)
print("finished")
time.sleep(1)
print("selection start")
generator2.prepare()
for i in range(10):
generator2.selectionChanged()
time.sleep(0.1)
print("finished")
time.sleep(1)
print("notification start")
generator3.prepare()
for i in range(3):
print(f"-{i}")
generator3.notificationOccurred(i)
time.sleep(1)
print("finished")
おわりに
.alloc().init()
と書けば良いことに気付くまで時間がかかりました。
参考サイト
[1] https://qiita.com/WorldDownTown/items/2b5a72e41a95763727bb (UIFeedbackGeneratorの使い方と便利に使えるライブラリ)
[2] https://note.com/tdksk/n/nb4498e59dcad (iPhone アプリでの Haptic Feedback による効果的なマイクロインタラクション)
[3] https://qiita.com/griffin_stewie/items/298f57ca3f1714ebe45c (iPhone 7 を入手したので早速 Taptic Engine の API を試してみました)
[4] https://developer.apple.com/documentation/uikit/uifeedbackgenerator?language=objc#2555399 (UIFeedbackGenerator)
[5] https://rubicon-objc.readthedocs.io/en/latest/tutorial/tutorial-2.html (Rubicon Tutorial 2)