LoginSignup
30
10

できる限りonTapGestureよりButtonを使おう(SwiftUI)

Last updated at Posted at 2023-05-09

はじめに

表題の通りです。
できる限り onTapGesture { ... } より Button を使いましょう。

// 🔺: `onTapGesture` を `Button` として使っている
FooView(foo: foo)
  .onTapGesture {
    print("FooView tapped.")
  }
  .accessibilityAddTraits(.isButton)

// ✅: `Button` を使っている
Button {
  print("FooView tapped.")
} label: {
  FooView(foo: foo)
}

Buttonlabel には View を渡せるので、リファクタリングも簡単です。

環境

  • OS:macOS Ventura 13.3.1
  • Xcode:14.3 (14E222b)
  • Swift:5.8

理由

できる限り onTapGesture { ... } より Button を使う理由を紹介します。

公式ドキュメントに記載されている

onTapGestureの公式ドキュメント に以下の記載があります。

Note

If you create a control that’s functionally equivalent to a Button, use ButtonStyle to create a customized button instead.
(ボタンと同等の機能を持つコントロールを作成する場合は、 ButtonStyleを使用して、代わりにカスタマイズされたボタンを作成します。)

Button と同等のコントロールなら Button を使いましょう、と明記されています。

最初の例では labelFooView をそのまま渡しましたが、 部品化するなら ButtonStyle を実装するのがいいと思います。

PrimitiveButtonStyle を使うのがいいとのことです。

タップ時にハイライトが付く

個人的には Button を使う一番の理由です。
onTapGesture だとタップ時にハイライトが付かないので、タップしたかどうかがわかりづらいです。
Button はデフォルトでハイライトが付きます。

ただ ButtonStyle を自作する場合、ハイライト処理を自前で実装する必要があります。

FloatingActionButtonStyle.swift
struct FloatingActionButtonStyle: ButtonStyle {
    let backgroundColor: Color
    let foregroundColor: Color

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .frame(width: 56, height: 56)
            .foregroundColor(foregroundColor)
            .background(backgroundColor)
            .cornerRadius(16)
+           .opacity(configuration.isPressed ? 0.5 : 1)
    }
}

といっても1行のみの実装で済みます。
Swift Playgroundsでスニペットを使って ButtonStyle を作ると、最初から書かれている処理です。

おわりに

タップ時の処理に onTapGesture を使っていたら、ぜひ Button に置き換えてハイライトが付くライフを送りましょう :relaxed:

参考リンク

30
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
10