9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

and factory.incAdvent Calendar 2023

Day 21

SwiftUIでのタップ処理の実装と応用

Last updated at Posted at 2023-12-20

はじめに

この記事はand factory.inc Advent Calendar 2023 21日目の記事です。
昨日は @twumo さんの【JetpackCompose】TabRowのインジケーターをカスタマイズするでした。

最近個人的に実務でSwiftUIに触れる機会が増えてきたので基本的なタップ周りの処理をまとめておこうと思います。

基本的なタップ処理

タップジェスチャ(onTapGesture)

最も基本的なタップジェスチャで、ビューがタップされたときのアクションを定義します。

import SwiftUI

struct TapGestureView: View {
    var body: some View {
        Text("タップしてください")
            .onTapGesture {
                print("タップされました")
            }
    }
}

ダブルタップジェスチャ

onTapGestureにcountパラメータを設定することで、ダブルタップなどの複数回のタップに対応できます。

import SwiftUI

struct DoubleTapGestureView: View {
    var body: some View {
        Text("ダブルタップしてください")
            .onTapGesture(count: 2) {
                print("ダブルタップされました")
            }
    }
}

カスタムタップ処理

ロングプレスジェスチャ

LongPressGestureを使用して、長押しジェスチャを検出します。

import SwiftUI

struct LongPressGestureView: View {
    var body: some View {
        Text("長押ししてください")
            .onLongPressGesture {
                print("長押しされました")
            }
    }
}

ハイパーリンク(.link修飾子)

テキストやビューにハイパーリンクを追加し、タップすると外部ブラウザでURLが開きます。

import SwiftUI

struct LinkView: View {
    var body: some View {
        Text("外部ブラウザで開く")
            .foregroundColor(.blue)
            .link(destination: URL(string: "https://www.example.com")!)
    }
}

合成されたジェスチャ(simultaneousGesture)

複数のジェスチャを同時に検出するために使用します。

import SwiftUI

struct SimultaneousGestureView: View {
    var body: some View {
        Text("タップまたは長押し")
            .onTapGesture {
                print("タップされました")
            }
            .simultaneousGesture(LongPressGesture().onEnded { _ in
                print("長押しされました")
            })
    }
}

SwiftUIのタップ処理の応用例

コンビネーションジェスチャの使用

複数のジェスチャを組み合わせることで、より複雑なユーザーインタラクションを作成できます。以下は、ドラッグとタップの組み合わせの例です。

import SwiftUI

struct CombinationGestureView: View {
    @State private var dragOffset = CGSize.zero

    var body: some View {
        Rectangle()
            .fill(Color.blue)
            .frame(width: 100, height: 100)
            .offset(dragOffset)
            .gesture(
                DragGesture()
                    .onChanged { value in
                        self.dragOffset = value.translation
                    }
                    .simultaneously(with: TapGesture().onEnded {
                        print("Rectangle Tapped")
                    })
            )
    }
}

カスタムジェスチャの作成

SwiftUIではカスタムジェスチャも作成できます。これにより、特定のユーザーインタラクションパターンに合わせた動作を実装できます。以下は、独自のジェスチャを定義する例です。

import SwiftUI

struct CustomGestureView: View {
    var customTapGesture: some Gesture {
        TapGesture()
            .onEnded {
                print("Custom Gesture Tapped")
            }
    }

    var body: some View {
        Circle()
            .fill(Color.red)
            .frame(width: 100, height: 100)
            .gesture(customTapGesture)
    }
}

UIKitと比較

SwiftUIの長所

  • コード量が少なく、直感的。
  • 状態の変化に応じて自動的にUIが更新される。

SwiftUIの短所

  • カスタムジェスチャーの柔軟性が少ない場合がある。
  • 特定の複雑なインタラクションの実装は難しいことがある。例えば、外部ブラウザを起動せずに、タップだけを検知するハイパーリンクのような機能を実装するのは、技術的な工夫を必要とすることがある。

おわりに

SwiftUIは、基本的なジェスチャからカスタムジェスチャまで、幅広い範囲のタップ処理が簡単に実装できます。しかし、特定の複雑なシナリオや高度なカスタマイズが必要な場合は、UIKitとの統合が必要となります。UIViewControllerRepresentableなどの機能を使い、SwiftUIとUIKitの長所を組み合わせることで、様々な動きを実現することが可能です。

この記事が、SwiftUIでのタップ処理の実装から応用までを学ぶ際の参考になれば幸いです。

明日のAdvent Calenderもお楽しみに!

9
2
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
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?