HOME > 問題解決一覧 > UITextViewをタップしたときのイベントを拾いたい

事象

UITextViewは標準でタップしたらソフトウェアキーボードを表示して文字入力するようになっていますが、それを止めて独自のイベント処理を実行したいと思っています。 どのように実装すればよいでしょうか。ご確認よろしくお願いします。

回答

UITextViewのタッチイベントを取得するためにはUITextViewを継承した独自クラスを作成してタッチイベント関連のメソッドをオーバーライドする必要があります。 下記のようにToucheEventTextViewというようなUITextViewを継承したクラスを実装します。

ToucheEventTextView.swift

class ToucheEventTextView: UITextView {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesBegan(touches , with: event)
        } else {
            super.touchesBegan(touches , with: event)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesEnded(touches , with: event)
        } else {
            super.touchesEnded(touches , with: event)
        }
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesCancelled(touches, with: event)
        } else {
            super.touchesCancelled(touches, with: event)
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesMoved(touches, with: event)
        } else {
            super.touchesMoved(touches, with: event)
        }
    }
}

タッチ認識したいViewControllerにTextViewを配置します。

1

identity inspectorを選択して先程作成したToucheEventTextViewを指定します。

2

下図のようにIBoutletで関連付けするとオブジェクト型がUITextViewからToucheEventTextViewになります。

3

ViewControllerにタッチ検知のコードを追加します。タッチを検知するタイミングとしてtouchesEndedにしていますがtouchesBeganなどお好みのデリゲートメソッドをオーバーライドしてください。 また、TextViewでソフトウェアキーボードが出ないように、またTextView内のテキストを選択しないようにtextView.isSelectable = falsetextView.isEditable = falseを追加してください。 タッチしたViewがTextViewかどうかの判別は該当ビューにtextView.tag = 123tagを追加して判別しています。

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var textView: ToucheEventTextView!
    override func viewDidLoad() {
        super.viewDidLoad()
        textView.isEditable = false
        textView.isSelectable = false
        textView.tag = 123
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesEnded")
        if isTouch(touches: touches, view: textView) {
            print("TextView touch!!")
        }
    }

    func isTouch(touches: Set<UITouch>, view:UIView) -> Bool{
        for touch: AnyObject in touches {
            let t: UITouch = touch as! UITouch
            if t.view?.tag == view.tag {
                return true
            } else {
                return false
            }
        }
        return false
    }
}

これでビルドしてみましょう。TextView部分をタップして下記のようにログが出力されるはずです。

4

コメント

この記事に関する質問やご意見・ご感想がありましたら、下記よりコメントください。
Githubアカウントでログインしていれば誰でも投稿できます。