読み込み中...

Swiftでタップイベントを検知する10のステップ

Swiftのロゴとタップイベントを表現する指のアイコン Swift
この記事は約24分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

Swiftを学んでいる初心者の方々の中には、ユーザのタップアクションを検知し、それに対して何らかの処理を行う方法について知りたいと思っている方が多いでしょう。

この記事を読めば、Swiftでタップイベントを検知する方法を完璧にマスターできるようになります。

具体的なサンプルコードを交えながら、初心者にもわかりやすく解説します。

●Swiftのタップイベントとは

スマートフォンやタブレットなどのタッチスクリーンデバイスでは、ユーザーのタッチ操作が主なインタラクションとなります。

Swiftでは、このようなタッチ操作を「タップイベント」として検知することができます。

アプリの中で何らかのボタンをタップしたときや、画面を長押ししたときなど、さまざまなタッチ操作を捉えて、アプリに新しい動きや反応をつけることができます。

○タップイベントの基本理解

タップイベントは、主に「UIGestureRecognizer」というクラスを使用して検知します。

このクラスを使用することで、タップだけでなく、ピンチ(2本指での拡大・縮小)、ロングプレス(長押し)などの様々なジェスチャを検知することができます。

例えば、画面上の特定の場所をタップしたときに、メッセージを表示するシンプルな例を考えてみましょう。

このコードでは「UITapGestureRecognizer」を使ってシングルタップを検知しています。

そして、タップされたときに実行されるアクションとして「showMessage」関数を設定しています。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // タップジェスチャーのインスタンスを作成
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(showMessage))
        self.view.addGestureRecognizer(tapGesture)
    }

    // タップされたときに呼び出されるメソッド
    @objc func showMessage() {
        print("画面がタップされました。")
    }
}

このコードを実行すると、画面をタップするたびに「画面がタップされました。」というメッセージがコンソールに表示されます。

これにより、ユーザのタップアクションを検知し、それに対して何らかの処理(この例ではメッセージの表示)を行うことができるようになりました。

●Swiftでのタップイベントの使い方

Swiftでタップイベントを利用するためには、まず基本的な使い方を理解することが重要です。

ここでは、UIButtonにタップイベントを追加する方法から、UIGestureRecognizerを使った一般的なタップイベントの検知方法までを詳しく解説します。

○サンプルコード1:UIButtonにタップイベントを追加する

UIButtonはiOSの基本的なUI要素の一つで、ボタンをタップすることで特定のアクションを実行できるように設計されています。

UIButtonにタップイベントを追加するには、以下の手順を参考にしてください。

このコードでは、UIButtonに「buttonTapped」という関数をタップイベントとして設定しています。

ボタンをタップすると、「ボタンがタップされました」というメッセージがコンソールに出力されます。

import UIKit

class ViewController: UIViewController {

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 200, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()

        button.setTitle("タップしてください", for: .normal)
        button.backgroundColor = .blue
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

        self.view.addSubview(button)
    }

    @objc func buttonTapped() {
        print("ボタンがタップされました。")
    }
}

このコードを実行すると、青色のボタンが表示され、そのボタンをタップすると、コンソールに「ボタンがタップされました」というメッセージが出力されることを確認できます。

○サンプルコード2:UIGestureRecognizerを使用したタップ検知

UIButton以外の要素、例えばラベルや画像などにタップイベントを追加する場合、UIGestureRecognizerを使用します。

下記のサンプルでは、画面全体のタップを検知する方法を示しています。

このコードでは、UITapGestureRecognizerを用いて、画面をタップした際のイベントを検知します。

そして、タップが検知された際に「screenTapped」という関数が実行され、画面がタップされたことがコンソールに表示されます。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(screenTapped))
        self.view.addGestureRecognizer(tapGesture)
    }

    @objc func screenTapped() {
        print("画面全体がタップされました。")
    }
}

このコードを実行すると、画面をどこをタップしても、コンソールに「画面全体がタップされました」というメッセージが表示されることを確認できます。

○サンプルコード3:ダブルタップイベントの検知

ダブルタップは、画面を2回連続でタップするアクションを指します。

特定のアクションや機能をダブルタップに割り当てることができます。

例えば、画像のズームイン/ズームアウトや特定のメニューの表示などに用いることが考えられます。

Swiftにおけるダブルタップイベントの検知には、UIGestureRecognizerのサブクラスであるUITapGestureRecognizerを使用します。

ここでは、ダブルタップを検知するためのサンプルコードを紹介します。

このコードでは、UITapGestureRecognizerを初期化し、ダブルタップを検知するための設定を行っています。

ダブルタップが検知された際には、doubleTappedという関数が呼び出され、コンソールに「ダブルタップされました」と表示されます。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
        doubleTapGesture.numberOfTapsRequired = 2
        self.view.addGestureRecognizer(doubleTapGesture)
    }

    @objc func doubleTapped() {
        print("ダブルタップされました。")
    }
}

ダブルタップのイベントを検知するためのキーとなるのは、numberOfTapsRequiredプロパティです。

このプロパティに2を設定することで、ダブルタップを検知するようになります。

上記のコードを実行し、画面を2回連続でタップすると、「ダブルタップされました」というメッセージがコンソールに表示されることが確認できます。

○サンプルコード4:長押しタップイベントの検知

長押しタップイベントは、画面を一定時間以上押し続けるアクションを指します。

このアクションは、メニューの表示やアイテムの移動、編集オプションの表示などに使用されます。

長押しのイベントを検知するためには、UIGestureRecognizerのサブクラスであるUILongPressGestureRecognizerを使用します。

下記のサンプルコードは、長押しイベントを検知するためのものです。

このコードでは、UILongPressGestureRecognizerを用いて、画面を長押ししたときのイベントを検知します。

そして、長押しが検知された際にlongPressedという関数が実行され、コンソールに「長押しされました」というメッセージが出力されます。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressed))
        self.view.addGestureRecognizer(longPressGesture)
    }

    @objc func longPressed() {
        print("長押しされました。")
    }
}

上記のコードを実行し、画面上を一定時間以上押し続けると、「長押しされました」というメッセージがコンソールに表示されることを確認できます。

●Swiftのタップイベントの応用例

Swiftにおけるタップイベントは、基本的な操作だけでなく、さまざまな応用例を持っています。

ここでは、アニメーションの実行やタップ位置の取得など、タップイベントを利用したいくつかの応用方法を詳しく解説していきます。

○サンプルコード5:タップイベントでアニメーション実行

タップイベントを使用して、画面上のオブジェクトにアニメーションを適用することができます。

例えば、ユーザーがボタンをタップしたときに、ボタンが回転するアニメーションを実行することが考えられます。

下記のコードでは、ボタンをタップすると、ボタンが360度回転するアニメーションを実行します。

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var rotateButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        rotateButton.addTarget(self, action: #selector(rotateAnimation), for: .touchUpInside)
    }

    @objc func rotateAnimation() {
        UIView.animate(withDuration: 1.0) {
            self.rotateButton.transform = self.rotateButton.transform.rotated(by: .pi)
        }
    }
}

このコードを実行すると、ボタンをタップするたびにボタンが半回転します。

○サンプルコード6:タップ位置の取得

タップイベントを使用して、ユーザーが画面上でタップした位置の座標を取得することも可能です。

これは、特定の場所をタップしたときの処理をカスタマイズするのに役立ちます。

下記のサンプルコードでは、画面上をタップすると、その位置の座標がコンソールに表示されます。

import UIKit

class ViewController: UIViewController {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let location = touch.location(in: self.view)
            print("タップされた位置:X: \(location.x), Y: \(location.y)")
        }
    }
}

このコードを実行すると、画面上の任意の場所をタップすると、そのX座標とY座標がコンソールに出力されます。

○サンプルコード7:タップによる画像の切り替え

Swiftのタップイベントを使用することで、ユーザーのタップ操作に応じて画像を切り替えることが可能です。

このような操作は、アプリのUIの一部として画像の変更や、ギャラリーアプリの次の画像への遷移などの機能として実装されることがあります。

下記のサンプルコードでは、画像が表示されているUIImageView上をタップすることで、別の画像に切り替わる機能を表しています。

import UIKit

class ImageChangeViewController: UIViewController {
    @IBOutlet weak var imageView: UIImageView!
    var isImageA = true

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(switchImage))
        imageView.addGestureRecognizer(tapGesture)
        imageView.isUserInteractionEnabled = true
    }

    @objc func switchImage() {
        if isImageA {
            imageView.image = UIImage(named: "imageB")
        } else {
            imageView.image = UIImage(named: "imageA")
        }
        isImageA.toggle()
    }
}

上記のコードでは、タップジェスチャーをUIImageViewに追加し、タップイベントが発生した際にswitchImageメソッドが呼び出されます。

このメソッド内で、現在表示されている画像を判定し、それに応じて次に表示する画像を設定しています。

このコードを実行すると、画像をタップするたびにimageAとimageBが交互に切り替わる動作を見ることができます。

○サンプルコード8:複数のタップイベントを同時に検知する

一つのUIView上で複数のタップイベントを同時に検知することもSwiftでは実現できます。

例えば、2本指でのタップや、3本指でのタップなどを判別し、それぞれ異なるアクションを実行することが考えられます。

下記のサンプルコードでは、1本指、2本指、3本指でのタップを判別し、それぞれ異なるアクションを実行します。

import UIKit

class MultiTapViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
        singleTap.numberOfTapsRequired = 1
        singleTap.numberOfTouchesRequired = 1
        view.addGestureRecognizer(singleTap)

        let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
        doubleTap.numberOfTapsRequired = 1
        doubleTap.numberOfTouchesRequired = 2
        view.addGestureRecognizer(doubleTap)

        let tripleTap = UITapGestureRecognizer(target: self, action: #selector(handleTripleTap))
        tripleTap.numberOfTapsRequired = 1
        tripleTap.numberOfTouchesRequired = 3
        view.addGestureRecognizer(tripleTap)
    }

    @objc func handleSingleTap() {
        print("1本指でのタップを検知しました")
    }

    @objc func handleDoubleTap() {
        print("2本指でのタップを検知しました")
    }

    @objc func handleTripleTap() {
        print("3本指でのタップを検知しました")
    }
}

このコードを実行すると、1本指でのタップ、2本指でのタップ、3本指でのタップをそれぞれ行ったとき、対応するメッセージがコンソールに出力されます。

○サンプルコード9:タップイベントで音を再生する

Swiftを用いてタップイベントを検知した際に音を再生することもできます。

これは、ユーザーのアクションにフィードバックを与えるためや、ゲームやエンターテインメントアプリなどで特定の音を出すために利用されることが多いです。

SwiftにはAVFoundationというフレームワークがあり、これを使用して簡単に音声の再生を実現することができます。

まず、プロジェクトに音声ファイル(例:sound.mp3)を追加し、その後下記のサンプルコードに沿って音声再生の機能を実装します。

import UIKit
import AVFoundation

class SoundPlayViewController: UIViewController {

    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(playSound))
        self.view.addGestureRecognizer(tapGesture)

        // 音声ファイルのパスを取得
        if let path = Bundle.main.path(forResource: "sound", ofType: "mp3") {
            let url = URL(fileURLWithPath: path)

            do {
                audioPlayer = try AVAudioPlayer(contentsOf: url)
                audioPlayer?.prepareToPlay()
            } catch {
                print("音声ファイルの読み込みに失敗しました")
            }
        }
    }

    @objc func playSound() {
        audioPlayer?.play()
    }
}

このコードでは、まずAVAudioPlayerのインスタンスを作成して音声ファイルを読み込んでいます。

そして、タップジェスチャーが検知されたときにplaySoundメソッドを実行し、音声を再生します。

このコードを実行すると、画面をタップする度に事前に準備したsound.mp3という音声が再生されることが確認できます。

○サンプルコード10:ドラッグ中のタップイベント検知

ドラッグ操作中にもタップイベントを検知し、その情報を利用することができます。

これは、例えばドラッグ操作中に指が画面から離れた瞬間に何らかのアクションを実行する場面などで役立ちます。

下記のサンプルコードでは、ドラッグ操作中のタップイベントを検知して、指が画面から離れた瞬間にラベルのテキストを更新します。

import UIKit

class DragTapViewController: UIViewController {

    @IBOutlet weak var statusLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let dragGesture = UIPanGestureRecognizer(target: self, action: #selector(handleDrag))
        self.view.addGestureRecognizer(dragGesture)
    }

    @objc func handleDrag(gesture: UIPanGestureRecognizer) {
        if gesture.state == .ended {
            statusLabel.text = "ドラッグ終了"
        }
    }
}

このコードでは、ドラッグ操作を検知するためのUIPanGestureRecognizerを使用しており、ドラッグ操作が終了したときにhandleDragメソッドを呼び出し、ラベルのテキストを更新しています。

このコードを実行すると、ドラッグ操作が終了した瞬間に画面上のラベルが「ドラッグ終了」というテキストに更新されることが確認できます。

●タップイベントの注意点と対処法

Swiftにおいてタップイベントを実装する際には、多くの開発者が直面するであろう注意点や問題、そしてそれらの対処法を理解しておくことが非常に重要です。

ここでは、Swiftでのタップイベントを実装する上での主な注意点と、それらの問題を解消するための対処法について詳しく解説します。

○多重タップの検知

画面に多数のタップ領域が存在する場合、ユーザーが意図せずに複数のタップイベントを同時にトリガーする可能性があります。

このような場合には、UIGestureRecognizernumberOfTapsRequiredプロパティを使用して、必要なタップ回数を指定することで問題を回避できます。

   let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped))
   tapGesture.numberOfTapsRequired = 1
   view.addGestureRecognizer(tapGesture)

上記のコードは、ユーザーが画面を1回タップした場合のみ、tappedメソッドが呼び出されるようにしています。

○長押しとの区別

一部のアプリケーションでは、タップと長押しの両方のイベントを検知する必要がある場合があります。

これらのイベントを正確に区別することは、意図しない動作を防ぐ上で必要です。

対処法として、UILongPressGestureRecognizerを使用して長押しイベントを検知し、それと通常のタップを区別します。

   let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressed))
   view.addGestureRecognizer(longPressGesture)

上記のコードでは、longPressedメソッドが長押しを検知した際に呼び出されるように設定されています。

○イベントの衝突

複数のジェスチャーレコグナイザが同じビューに追加される場合、それらのジェスチャーが競合することがあります。

例えば、スワイプジェスチャーとタップジェスチャーが同時に検知されることが考えられます。

このような場合、UIGestureRecognizerDelegateのメソッドを使用して、どのジェスチャーを優先するか、または同時に認識させるかを制御できます。

   tapGesture.delegate = self

   func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
       return true
   }

上記のコードは、タップジェスチャーが他のジェスチャーと同時に検知される場合でも、同時に認識させるようにしています。

●カスタマイズの方法

Swiftを使用してタップイベントを実装する際、ただ検知するだけでなく、そのイベントをカスタマイズする方法も知っておくと、更に多彩なアプリケーションの実装が可能になります。

タップイベントのカスタマイズは大きく2つに分けられます。

一つはイベントの動作自体をカスタマイズする方法、もう一つはデザインや見た目をカスタマイズする方法です。

ここでは、それぞれのカスタマイズ方法を具体的に解説していきます。

○イベントのカスタマイズ

□ジェスチャーの感度調整

タップイベントの感度を調整することで、ユーザーの異なるタップの強さや速さに対応することができます。

例えば、強くタップされた場合や、早く連続してタップされた場合に異なるアクションを起こすことが考えられます。

   let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped))
   tapGesture.numberOfTapsRequired = 2 // 2回タップされたときのみ反応
   view.addGestureRecognizer(tapGesture)

上記のコードは、画面が2回連続でタップされた場合のみ、tappedメソッドが呼び出されるように設定しています。

□ジェスチャーの優先度設定

複数のジェスチャーが同じビューに設定されている場合、どのジェスチャーを優先して検知するかを設定することができます。

   let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
   tapGesture.require(toFail: swipeGesture)
   view.addGestureRecognizer(swipeGesture)

上記のコードでは、スワイプジェスチャーが検知されなかった場合のみ、タップジェスチャーが検知されるようになっています。

○デザインのカスタマイズ

□タップエフェクトの追加

タップした際の視覚的なエフェクトを追加することで、ユーザーへのフィードバックを向上させることができます。

   @objc func tapped(_ sender: UITapGestureRecognizer) {
       let tapLocation = sender.location(in: view)
       let effectView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
       effectView.center = tapLocation
       effectView.backgroundColor = UIColor.red.withAlphaComponent(0.5)
       view.addSubview(effectView)

       UIView.animate(withDuration: 0.5, animations: {
           effectView.alpha = 0
       }) { (finished) in
           effectView.removeFromSuperview()
       }
   }

このコードを実行すると、タップされた場所に赤い円が現れ、徐々に透明になって消えるアニメーションが実行されます。

これにより、ユーザーはタップが正確に認識されたことが視覚的にわかりやすくなります。

□タップ領域のデザイン変更

タップ可能な領域のデザインを変更することで、どの部分がタップ可能であるかをユーザーに明示的に表すことができます。

   let tapArea = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 50))
   tapArea.backgroundColor = UIColor.blue
   view.addSubview(tapArea)

上記のコードは、画面に青色の長方形のタップ領域を追加するものです。

このようにデザインを変更することで、ユーザーはタップ領域を直感的に理解することができます。

まとめ

Swiftでのタップイベントの実装は、アプリケーションをよりユーザーフレンドリーにするための重要な要素の一つです。

本記事では、タップイベントの基本的な検知方法から、カスタマイズ方法に至るまでのステップを詳細に解説しました。

Swiftを使用したアプリケーション開発を進める際には、上記の内容を参考にして、ユーザーエクスペリエンスを高めるためのタップイベントの実装を検討してみてください。

ユーザーが直感的に操作できるアプリケーションは、高い評価や多くの利用者を獲得する可能性があります。