【SwiftUI】UX向上のために、HapticFeedbackを使ってみる

# UX向上のために

市場に多くのアプリが溢れる中、
他のアプリと差別化するためには何をするべきでしょうか？

1つの答えとして、「ユーザー体験(UX)を向上させる」ことだと思います。

では、アプリ開発において、UXを向上させるには？

...

Appleが提供するUXを向上させるものとして、「触覚フィードバック」があります。

> It’s important to build a clear, causal relationship between each haptic and the action that causes it so people learn to associate certain haptic patterns with certain experiences.

> 訳：それぞれの触覚とそれを引き起こす行動の間に明確な因果関係を築き、人々が特定の触覚パターンを特定の経験と関連付けることを学ぶようにすることが重要なのだ。

参照：[Playing haptics | Apple Developer Documentation](https://developer.apple.com/design/human-interface-guidelines/playing-haptics)

公式にあるように、開発者が意識をすることが大切ですが、
そもそもどのようなものがあるのか知らないと意識することはできません。

今回は、iPhoneで利用することのできる「触覚フィードバック」を体験してみました。
最後に今回作成したものをまとめたGitを展開しているので、気になる方はぜひお試しください。

# 開発環境

Xcode 15.4
Swift 5.10

# 実際に触ってみた

iPhoneで利用できるフィードバックは、公式によると
- Notification (Success, Warning, Error)
- impact (カスタム可)
- selection

の合計3種類(厳密に言うと、5種類)とありますが、
実際に触ってみると、
- increase
- decrease

も「selection」と同じようなフィードバックがありました。


```swift
/// サンプル一覧
struct HapticFeedbackSampleListView: View {

    @State var alignment = false
    @State var decrease = false
    @State var error = false
    @State var impact = false
    @State var increase = false
    @State var levelChange = false
    @State var pathComplete = false
    @State var selection = false
    @State var start = false
    @State var stop = false
    @State var success = false
    @State var warning = false

    var body: some View {
        List {
            Section(header: Text("iOS対応")) {
                Button("success") {
                    success.toggle()
                }
                Button("warning") {
                    warning.toggle()
                }
                Button("error") {
                    error.toggle()
                }
                Button("impact") {
                    impact.toggle()
                }
                Button("increase") {
                    increase.toggle()
                }
                Button("decrease") {
                    decrease.toggle()
                }
                Button("selection") {
                    selection.toggle()
                }
            }
            Section(header: Text("iOS未対応")) {
                Button("alignment") {
                    alignment.toggle()
                }
                Button("levelChange") {
                    levelChange.toggle()
                }
                Button("pathComplete") {
                    pathComplete.toggle()
                }
                Button("start") {
                    start.toggle()
                }
                Button("stop") {
                    stop.toggle()
                }
            }
        }
        .padding()
        .sensoryFeedback(.alignment, trigger: alignment)
        .sensoryFeedback(.decrease, trigger: decrease)
        .sensoryFeedback(.error, trigger: error)
        .sensoryFeedback(.impact, trigger: impact)
        .sensoryFeedback(.increase, trigger: increase)
        .sensoryFeedback(.levelChange, trigger: levelChange)
        .sensoryFeedback(.pathComplete, trigger: pathComplete)
        .sensoryFeedback(.selection, trigger: selection)
        .sensoryFeedback(.start, trigger: start)
        .sensoryFeedback(.stop, trigger: stop)
        .sensoryFeedback(.success, trigger: success)
        .sensoryFeedback(.warning, trigger: warning)
    }
}
```

# 応用してみる

フォードバックのある「いいねボタン」を作ってみます。
このページではフィードバックは体験できませんが、下部に記載したGitから実際に動作確認ができます。
この例から簡単にフォードバックを設定できることがわかりますね。

![いいねボタンサンプル.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806185/63faacd5-cadf-6c00-f138-4acbc84a8c84.gif)


```swift
struct GoodButtonSampleView: View {

    @State var isGood = false

    var body: some View {
        Button {
            isGood.toggle()
        } label: {
            Image(systemName: isGood ? "hand.thumbsup" : "hand.thumbsup.fill")
                .renderingMode(.template)
                .resizable()
                .frame(width: 40, height: 40)
                .foregroundStyle(.yellow)
                .symbolEffect(.bounce, options: .repeat(1), value: isGood)
        }
        .sensoryFeedback(.impact, trigger: isGood)
    }
}
```

# まとめ

実際、触覚フィードバックはなくても何も問題ないです。
しかし、少しでも他のアプリとの差別化やUX向上を求めるなら入れない手はないですね。

ただ、今回の例のように簡単に追加できるのは、
iOS17以上になるので、そこだけがネックになると感じました。

---

https://github.com/NanbanTaro/SwiftUI-Sample-HapticFeedback/tree/main