【Swift】テキストフィールドに設定できるイベントの種類と動作について。(Swift 2.1、XCode 7.2)
前回の記事で、ボタン(UIButton)を押したときのイベントについて説明した。⇒「記事」
その流れを受けて、本記事ではテキストフィールドに設定できるイベントの種類と動作の違いについて説明する。
テキストフィールドとは、アプリに文字列を入力するための枠のことをいう。ユーザー名やパスワード、メッセージなどをいつも入力しているアレである。
そのテキストフィールドに「文字を入力し始めた」、「文字を入力し終わった」などのイベントを検知してアプリに動作させることができる。
まずは、テキストフィールドとラベルの部品をアプリ画面に配置し、ソースコードとコネクションを作成する。部品を配置してテストするまでの一連の流れは以前の記事で説明しているので、詳しくはそちらを参照されたし。⇒「記事」
テキストフィールドのイベントを受けるテストなので、Connectionに「Action」を設定すること。
下図はEventに設定できる項目の一覧。ボタンを押したときのイベントと同じように、タップ(Touch Up, Touch Down)したり、ドラッグ(Touch Drag)したときのイベントも使うことができる。今回はテキストフィールドならではイベントを説明する。
コネクションを作ったあとのソースコードは以下になる。イベントを受けるメソッドでは、引数で渡ってきたインスタンスのtextプロパティの値をラベルに設定する処理を記述した(青網掛箇所)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// // ViewController.swift // TestProject // import UIKit class ViewController: UIViewController,UITextFieldDelegate { //ラベル @IBOutlet weak var testLabel: UILabel! //イベントを受けるメソッド @IBAction func catchEvent(sender: UITextField) { testLabel.text = sender.text } //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } //最初からあるメソッド override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
上記コードをイベントの種類ごとに動かしてみよう。なお、テキストフィールドをタップすると画面下にキーボードが現れる処理は、UITextFieldに最初から備わっている機能である。
Did End On Exit
「改行」または「return」キーを押してキーボードが閉じられたあとにメソッドが呼び出される。
Editing Changed
テキストフィールドの文字が変更される度にメソッドが呼び出される。テキストフィールドの入力値をリアルタイムに監視したい場合に使える。
先ほどのイベント「Did End On Exit」では「改行」または「return」キーを押したときにキーボードが自動で閉じられるが、そのイベント以外はキーボードは自動で閉じられないので、キーボードを閉じる処理を自分で実装する必要がある。
その処理を実装するにはデリゲートという機能を利用する。
デリゲートとは、部品のイベントが発生したら他のクラスにイベントの処理を任せる機能である。イベントの処理を任されるクラスをデリゲートクラスという。
デリゲートクラスになるには、各部品の種類ごとのデリゲートプロトコルを適用する必要がある。例えば、テキストフィールド(UITextField)のデリゲート先のクラスを作りたかったら、UITextFieldDelegateプロトコルを適用したクラスを作成する。
以下のコードはテキストフィールドのデリゲート先になるためにUITextFieldDelegateプロトコルを適用したクラスの例。
上図ではデリゲートするクラスと、されるクラスを分けた形にしているが、デリゲートするクラス自身がデリゲート先になることもできる。自分で自分に頼むみたいなイメージ。
プロパティ宣言にテキストフィールドの部品を追加し、初期化メソッドの中でテキストフィールドのdelegateプロパティに自分自身を設定することで自分自身がデリゲート先になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/* ** デリゲートの定義 */ import UIKit class ViewController: UIViewController,UITextFieldDelegate { //ラベル @IBOutlet weak var testLabel: UILabel! //テキストフィールド @IBOutlet weak var testTextField: UITextField! //イベントを受けるメソッド @IBAction func catchEvent(sender: UITextField) { testLabel.text = sender.text } //初期化メソッド(最初からある) override func viewDidLoad() { super.viewDidLoad() //デリゲート先を指定 self.testTextField.delegate = self } //警告受信メソッド(最初からある) override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
そして、以下のメソッドをViewControllerクラスの中に記述すると、キーボードの「改行」または「Return」キーが押されたときにデリゲートとしてこのメソッドが呼び出される。戻り値は最後の改行を出力する(true)、しない(false)の違いである。
1 2 3 4 5 6 7 |
//改行、または、Returnキーが押されたら呼び出されるメソッド func textFieldShouldReturn(textField:UITextField) -> Bool { //キーボードをしまう self.view.endEditing(true) return false } |
これでキーボードが閉じるようになった。
Editing Did Begin
テキストフィールドをタップした時点でメソッドが呼び出される。今回のテストはテキストフィールドの値をラベルに設定するものなので、最初のタップでラベルの値が空になる。文字列の入力を確定したあと再度テキストフィールドをタップすると、確定した文字列がラベルに設定される。
Editing Did End
キーボードをしまうメソッドを呼び出したときにこのイベントのメソッドが呼び出される。
デリゲートメソッドの処理がすべて終わったあとにイベントメソッドが呼ばれるのではないことを覚えておきたい。
例えば、以下のコードのようにイベントメソッドの中でラベルを「 BBB」に設定する処理を入れるのと、キーボードをしまうメソッドを呼び出した直後にラベルを「AAA」に設定する処理を入れた場合、ラベルの値は最終的に「AAA」になる。
要するに、イベントメソッドはendEditingメソッドのすぐあとに実行されるということだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* ** デリゲートクラスの実装 */ import UIKit class ViewController: UIViewController,UITextFieldDelegate { //ラベル @IBOutlet weak var testLabel: UILabel! //テキストフィールド @IBOutlet weak var testTextField: UITextField! //イベントメソッド @IBAction func catchEvent(sender: UITextField) { testLabel.text = "BBB" } //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先を指定 self.testTextField.delegate = self } //デリゲートメソッド func textFieldShouldReturn(textField:UITextField) -> Bool { //キーボードをしまう self.view.endEditing(true) testLabel.text = "AAA" return false } } |
「Did End On Exit」はデリゲートを実装しなくてもキーボードが勝手に閉じてくれるので記述が楽になる。一方、「Editing Did End」は必ずデリゲートを実装しなければならないが、キーボードをしまう前に入力値チェックなどの処理を入れるのに使える。使い分けよう。