【Swift】UITextViewの使い方。複数行を入力、改行もできるテキストフィールド。(Swift 2.1、XCode 7.2)
UITextViewとは
本記事ではSwiftで使える部品のUITextView(以下、テキストビュー)について説明する。
テキストビューとは、複数行の文字を入力できるフィールドである。
テキストビューに似ている部品にUlLabel(以下、ラベル)とUITextField(以下、テキストフィールド)がある。⇒「記事」
ラベルは文字を表示するだけの部品で、ラベルをタップしてキーボードから直接ラベルの値を変更するような使い方ができない。テキストフィールドは文字を入力できる部品だが、入力できる行数が1行に制限されている。
一方、テキストビューは改行も含めて複数行を入力、表示できるので、長文を扱いたいときに役に立つ。
UITextViewを試す
テキストビューを実際に使ってみよう。
デバイス画面にテキストビューを配置する(下図赤枠)。背景色を分かりやすくするために、下図紫枠のアトリビュートインスペクタボタンを押して設定画面を開きBackgroundを黄緑色に変更する。ついでにPlainの中身を消してサンプルの文章を消しておく。
このままシュミレーターを起動すればテキストビューをタップして文字を入力することができるが、キーボードを閉じることができない。
閉じるボタンを追加する
テキストフィールドの場合は「改行」ボタンを押したときのイベント検知からキーボードを閉じる処理を実装したが、テキストビューの「改行」ボタンはそのまま改行として機能させたい。
そこで、テキストビューではキーボードを閉じるための新たなボタンをキーボードに追加する。
下図紫枠のアシスタントエディタボタンを押してViewController.swiftを開く。ドラッグ&ドロップでテキストビューをソースコードまで運んで吹き出しの設定画面を表示させる。Connectionに「Outlet」、Nameに「testTextView」を入力してConnectボタンを押す。これでソースコードからテキストビューを操作できるようになった。
ボタンを追加する方法について説明する。下図のような赤色のボタンを青色のビューに追加し、それをキーボードのアクセサリに登録する。ボタンはビューの右端に配置されるように画面の幅をもとに位置を算出する。ボタンの位置はビューの左角からの距離になるので、X方向に「画面幅ーボタン幅」、Y方向は0とする。
キーボードのアクセサリにボタンを直接登録することもできるが、その場合ボタンが幅いっぱいに押せてしまうため、このような方法をとっている。
ViewController.swiftを開き、以下のコードに変更する。
UITextViewDelegateプロトコルを適用し、閉じるボタンが押されたときのメソッドでキーボードを閉じる。
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 38 39 40 41 42 43 44 |
// // ViewController.swift // import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet weak var testTextView: UITextView! override func viewDidLoad() { super.viewDidLoad() //ビューを作成する。 let testView = UIView() testView.frame.size.height = 60 testView.backgroundColor = UIColor.blueColor() //「閉じるボタン」を作成する。 let closeButton = UIButton(frame:CGRectMake(CGFloat( UIScreen.mainScreen().bounds.size.width)-70, 0, 70, 50)) closeButton.setTitle("閉じる", forState:UIControlState.Normal) closeButton.backgroundColor = UIColor.redColor() closeButton.addTarget(self,action:"onClickCloseButton:", forControlEvents: .TouchUpInside) //ビューに「閉じるボタン」を追加する。 testView.addSubview(closeButton) //キーボードのアクセサリにビューを設定する。 testTextView.inputAccessoryView = testView //テキストビューのデリゲート先にこのインスタンスを設定する。 testTextView.delegate = self } //「閉じるボタン」で呼び出されるメソッド func onClickCloseButton(sender: UIButton) { //キーボードを閉じる testTextView.resignFirstResponder() } } |
以下が実際のプレイ動画
横画面でもボタンを右端に表示する
しかし、上記の実装には欠点がある。「閉じるボタン」の位置が固定されているため、画面を横に倒すと「閉じるボタン」が画面中央に表示されてしまうのだ。横画面に対応する場合はこれだと違和感がある。
そこで、ViewController.swiftを以下のように修正し、ボタンが必ずビューの右端に配置される制約を追加する。
具体的には、ボタンの幅の制約、高さの制約、ボタンの上端とビューの上端を同じにする制約、ボタンの右端とビューの右端を同じにする制約を追加する。
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
// // ViewController.swift // import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet weak var testTextView: UITextView! override func viewDidLoad() { super.viewDidLoad() //ビューを作成する。 let testView = UIView() testView.frame.size.height = 60 testView.backgroundColor = UIColor.blueColor() //閉じるボタンを作成する。 let closeButton = UIButton() closeButton.setTitle("閉じる", forState:UIControlState.Normal) closeButton.backgroundColor = UIColor.redColor() closeButton.addTarget(self,action:"onClickCloseButton:", forControlEvents: .TouchUpInside) //ビューに閉じるボタンを追加する。 testView.addSubview(closeButton) //Autoresizingの変換をオフにする。 closeButton.translatesAutoresizingMaskIntoConstraints = false //ボタンの幅の制約を追加する。 testView.addConstraint(NSLayoutConstraint( item: closeButton, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 0.0, constant: 70)) //ボタンの高さの制約を追加する。 testView.addConstraint(NSLayoutConstraint( item: closeButton, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 0.0, constant: 50)) //ボタンの右端とビューの右端を揃える制約を追加する。 testView.addConstraint(NSLayoutConstraint( item: closeButton, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: testView, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 0)) //ボタンの上端とビューの上端を揃える制約を追加する。 testView.addConstraint(NSLayoutConstraint(item: closeButton, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: testView, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0)) //キーボードにビューを追加する。 testTextView.inputAccessoryView = testView //テキストビューのデリゲート先にこのインスタンスを設定する。 testTextView.delegate = self } //閉じるボタンで呼び出されるメソッド func onClickCloseButton(sender: UIButton) { testTextView.resignFirstResponder() } } |
以下が実際のプレイ動画。縦画面、横画面の両方で「閉じるボタン」が右端に表示されるようになった。