#はじめに
iOS10からUIKitにはUIFeedbackGeneratorというAPIが追加されており、簡単にHapticFeedbackを実装することができました。
iOS13が公開され、UIFeedbackGeneratorに比べてカスタマイズできるHaptic Feedbackを作成できるようになったのですが、UIFeedbackGeneratorがあるUIKitにではなく、新しくCore HapticsというFrameworkが追加されました。
この記事はCore Hapticsとはどういう物なのか、実装方法などを簡単にまとめてみました。
###HapticFeedbackとは
UISwitchでON/OFFを切り替えたり、UISliderでSliderを端までスワイプしたり、UIDatePickerでスクロールした時などの特定のアクションを行うと起きる振動のことで、たくさんの場所に組み込まれており、いくつかの種類が存在します
#Core Hapticsとは
対応機種
iPhone8以降の全機種で使用することができます。
UIFeedBackGeneratorとCore Haptics
UIFeedBackGeneratorはNotification,Impact,Selectionなど、アクションを起こしたユーザーに対してFeedBackを行うことにより、UXを向上させることが目的とされています。
対して、Core Hapticsは自分でHapticFeedBackを内容、使うタイミングなどを自由に設定したい場合に使用します。
他のAPI(Core Animation, AVAudioEngine)との連動も可能なことや、Core HapticsはAudioAPIであり、今までAppleが実装していた音と連動して使用することなど(例:UIDatePickerのスクロール)も可能なので、UIFeedBackGeneratorに比べて豊かな表現を行うことができます。
WWDCでは特に活用できるジャンルとして、ゲーム、ARなどが挙げられていました・
#コード
それでは実際に実装しながら見ていきたいと思います。
モジュールのインポート
import CoreHaptics
##HapticEngine作成
var hapticEngine: CHHapticEngine?
do {
hapticEngine = try CHHapticEngine()
try hapticEngine?.start()
} catch {
print("Error \(error)")
}
・CHHapticEngineにはcapabilitiesForHardware
というメソッドが存在しており、HapticEngineを作成する前にデバイスが実行されているデバイス環境でHapticsFeedBackがサポートされているか確認することもできます。
guard CHHapticEngine.capabilitiesForHardware().supportsHaptics else { return }
・そのほかにもstoppedHandler
,resetHandler
が用意されており、アプリケーション以外の動作でエンジンが終了される時などに使用できるコールバックも用意されています。
var stoppedHandler: CHHapticEngine.StoppedHandler { get set }
var resetHandler: CHHapticEngine.ResetHandler { get set }
HapticEventParameterを元にHapticEventを作成
再生するコンテンツを作成します
//EventParameterを作成
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1)
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1)
//EventParameter,EventType,Time,からEventを作成します。
let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: 0)
EventParameterを作成
・Eventで使われるParameterを作成します、ParameterTypeとしては音の強さ、明瞭さなど複数の種類が存在します。
EventParameter,EventType,Time,からEventを作成します。
・先ほど作成したEventParameter,EventType,Time,からEventを作成、eventTypeとしては単発で短い動き、継続的、音とHapticFeedBackを連動させるなどがあります。
再生
do {
//先ほど作ったEventからPatternを作成
let hapticPattern = try CHHapticPattern(events: [event], parameters: [])
//PatternのPlayerを作成
let hapticPlayer = try hapticEngine?.makePlayer(with: hapticPattern)
try hapticPlayer?.start(atTime: CHHapticTimeImmediate)
} catch let error{
print("Error: \(error)")
}
・イベントを1つのPatternとしてラップして、そのPatternに対するPlayerを作成します。
これがCoreHapticsの基本的なコードになります
Dynamic Parameter
UIFeedBackGeneratorとの違いの1つとして、Event Parameterの値を増減することや複数の動きを組み合わせる事が可能です。
・上記のCHHapticEventは単純な振動のみですが、下記のようにするとrelativeTimeを元にタイムラインを設定することにより、複数イベントを作成して、パターンとして扱うこともできます。
//単発のEvent
let short1 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0)
let short2 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0.2)
let short3 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0.4)
let short4 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0.6)
let short5 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0.8)
let short6 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 1.0)
//継続的なEvent
let long1 = CHHapticEvent(eventType: .hapticContinuous, parameters: [], relativeTime: 1.2, duration: 0.5)
let long2 = CHHapticEvent(eventType: .hapticContinuous, parameters: [], relativeTime: 1.8, duration: 0.5)
let long3 = CHHapticEvent(eventType: .hapticContinuous, parameters: [], relativeTime: 2.4, duration: 0.5)
#最後に
今回紹介したのはCore Hapticsの簡単な部分にすぎません、他のPatternの作成方法として、APHP(Apple Haptic Audio Pattern)と呼ばれるファイルを用いてコードからHapticPatternを分離させる方法や、CHHapticParameterCurveといった再生中に値を増減させるなどより自由度の高い作成方法もありますので、気になった方はWWDCの動画やDocumentなどをご覧になってみてください。
ありがとうございました。
#参考リンク