本記事では、iOS14+から使用可能なSwiftUIの「TextEditor」について見ていきます。
TextEditorは、複数行のテキストが入力できるフィールドを提供します。
上記のように、簡易的なコードで入力ボックスを実装することができます。
ただし単体だと少し機能が足りないため、モディファイアなど各種オプションを用いて必要な機能を肉付けしていきます。
本記事のソースコード
[ 本記事はこんな人におすすめ ]
・SwiftUIでアプリ開発をしている
・複数行の入力ボックスを作成したい
・TextEditorの使い方を知りたい
イニシャライザ(初期化子)
TextEditor
のイニシャライザは非常にシンプルで、引数パラメータはBinding<String>
型の「text:」1つのみです。
/// TextEditorのイニシャライザ(初期化子)
init(text: Binding)
【パラメータ】
text:
編集対象テキスト(String)への参照(Binding)を指定する。
サイズの仕様について
TextEditor
は自身にサイズの指定が無い場合、入力ボックスの幅を可能な限り広く取ります。
.frame
モディファイアなどでサイズを指定することで、入力ボックスのサイズをコントロールできます。
基本的な使い方
基本コード
以下は、TextEditor
のシンプルな実装コードです。
String型の状態変数を用意し、引数「text:」と紐付けます。
/// TextEditorのシンプルな実装コード
struct BasicTextEditor: View {
@State private var inputText = ""
var body: some View {
// 複数行の入力ボックス
TextEditor(text: $inputText)
.frame(width: 300, height: 300)
.border(.black) // 枠線
}
}
これだけの実装で、複数行の入力ボックスを画面に配置することができます。
ただし、今のままのプレーンな状態だと、実際にアプリ内で使うには少し不便な仕様がいくつか存在します。
例えば以下のようなものが挙げられます。
・プレースホルダーが無い(未入力時に表示するガイドテキスト)
・キーボードを閉じる手段が無い(returnキーが改行であるため)
etc…
後述に挙げるオプションを用いて、これらを補助する機能を含め、外観やシステムに肉付けをしていきます。
スタイル(外観)の制御
枠線をつける(border)
.border
モディファイアで入力ボックスに枠線を追加できます。引数「width:」でライン幅の調節も可能です。
// 入力ボックスに枠線を追加する
TextEditor(text: $inputText)
.frame(width: 400, height:150)
.border(.gray, width: 5) // ⬅︎
ボックスとテキストの間隔を空ける(padding)
サイズ指定の前に.padding
モディファイアを付与すれば、入力ボックスとテキストの間隔を空けることができます。
// 枠との間隔を空ける
TextEditor(text: $inputText)
.padding() // ⬅︎
.frame(width: 400, height:150)
.border(.gray, width: 5)
文字のスタイルを変更する
.font
や.fontWeight
などの文字スタイル変更は、TextEditorの入力文字にも適用されます。
また、.foregroundColor
で文字色を変更できます。
// 文字スタイルを変更する
TextEditor(text: $inputText)
.font(.title) // ⬅︎
.fontWeight(.bold) // ⬅︎
.foregroundColor(.orange) // ⬅︎
.frame(width: 400, height:150)
.border(.gray, width: 5)
テキストの行間を変更する(lineSpacing)
.lineSpacing
モディファイアを使うことで、テキストの行ごとのスペースを調整できます。
// テキストの行間を変更する
TextEditor(text: $inputText)
.lineSpacing(30) // ⬅︎
.frame(width: 400, height:150)
.border(.gray, width: 5)
テキストの整列ルールを制御する(multiLineTextAlignment)
.multiLineTextAlignment
モディファイアでテキストの整列位置をコントロールできます。
// テキストの整列ルールを制御する
TextEditor(text: $inputText)
.multilineTextAlignment(.leading) // ⬅︎
.frame(width: 400, height:100)
.border(.gray, width: 5)
プレースホルダーを追加する
TextEditorには、TextFieldのようなプレースホルダー機能はデフォルトで用意されていないため、自作する必要があります。
以下は、TextEditorにプレースホルダーを追加するコードの一例です。
/// TextEditorにプレースホルダーを追加する
TextEditor(text: $inputText)
.frame(width: 400, height:150)
.border(.gray, width: 5)
.overlay(alignment: .topLeading) {
// 未入力の時、プレースホルダーを表示
if inputText.isEmpty {
Text("ここに文字を入力してください。")
.allowsHitTesting(false) // タップ判定を無効化
.foregroundColor(Color(uiColor: .placeholderText))
.padding(6)
}
}
・.overlay(alignment: .topLeading)で左上にビューを重ねる
・if inputText.isEmpty{…}で未入力時のみビューを表示
・.allowsHitTesting(false)でプレースホルダーのタップ判定は無効化
ビューに対して.allowsHitTesting(false)を付与することで、対象ビューのタップ判定を無効化できます。
プレースホルダー文字は、.overlayによってTextEditorの前面に配置されています。そのため、ユーザーがプレースホルダー文字の部分をタップした際、TextEditorに対してタップ判定が実行されず、キーボードが表示されないという問題があります。
.allowsHitTesting(false)を用いることで、意図しないビューに対してのタップ判定を防ぐことができ、キーボードが問題なく表示されるようになります。
システムの制御
キーボードタイプを指定する(keyboardType)
.keyboardTypeモディファイアで入力キーボードのタイプを指定できます。
/// キーボードタイプの設定
TextEditor(text: $inputText)
.keyboardType(.numberPad) // ⬅︎
.frame(width: 400, height:150)
.border(.gray, width: 5)
上記のような数字入力専用タイプの他にも、URL入力用や電話番号入力用など、複数のタイプが用意されています。
以下のドキュメントに各タイプが列挙されているので、チェックしてみてください。
単語の自動修正をOFFにする(autocorrectionDisabled)
デフォルトだと、間違えた単語を入力した際にシステムが自動で予測した単語に修正する機能が備わっています。
この機能をOFFにしたい場合は、.autocorrectionDisabledモディファイアに「true」を渡します。
// 単語の自動修正機能をOFFにする
TextEditor(text: $inputText)
.autocorrectionDisabled(true) // ⬅︎
.frame(width: 400, height:150)
.border(.gray, width: 5)
編集不可にする(disabled)
TextEditorに.disabledモディファイアを付与し、「true」を渡すことで、テキストの編集を不可能にすることができます。
これにより、TextEditorをタップしてもキーボードが表示されなくなります。
// TextEditorの編集可能/不可能をコントロールする
TextEditor(text: $inputText)
.disabled(true) // trueで編集不可
.frame(width: 400, height:150)
.border(.gray, width: 5)
また、Bool値を状態変数として.disabledに渡しておけば、プログラム制御で「編集させたくない場面ではtrue、編集してもいい場面ではfalse」といったような動的なコントロールも可能です。
フォーカスを制御する(FocusState)
以下のように、TextFieldはReturnキーでキーボードを閉じることができます。
対してTextEditorの場合、Returnキーのボタン位置には「改行」が配置されており、キーボードは閉じられません。
つまり、TextEditorで入力キーボードを閉じるためには、プログラムでフォーカスを制御する必要があります。
以下に、フォーカスをプログラムで制御する実装例を挙げます。
1. @FocusStateが付与されたBoolプロパティを用意する
2. .focusedモディファイアをTextEditorに付与し、Boolプロパティを紐付ける
// フォーカス状態を監視するBoolプロパティ
@FocusState var isFocused: Bool
TextEditor(text: $inputText)
.focused($isFocused) // ⬅︎
この手順により、TextEditorのフォーカス状態をBoolプロパティisFocusedが監視するようになります。
あとはキーボードを閉じたいタイミングで、Boolプロパティに「false」を代入すれば、キーボードが閉じてくれます。
isFocusedがfalseになることで、.focusedモディファイアにて、TextEditorがフォーカスを失います。フォーカスを失うと入力状態がキャンセルされますので、キーボードが閉じられます。
こちらの実装例では、Colorビューにタップジェスチャーを付与し、キーボードを閉じる処理を置いています。
まとめ
以上、SwiftUIの複数行テキスト入力ビュー「TextEditor」についてでした!
要点をまとめておきます。
・複数行のテキスト入力を提供する
・サイズ指定が無い場合、可能な限り広い幅を取る
・必要に合わせて、モディファイアなど各種オプションで肉付けしていく
・キーボードを閉じるにはプログラムでの制御が必要
複数行の入力ボックスは、アプリ内でも使用したい場面が多くあるかと思います。
ぜひ本記事を利用して、TextEditorを自作アプリに取り入れてみてください!
参考になれば幸いです。
\ SHARE /
アプリ開発が学べる勉強会を開催中!
CodeCandyではアプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。
徹底した基礎学習からマスターするiPhoneアプリ開発集中オンライン講座開講!
本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!
まずは、現役エンジニアに相談できる無料相談をご利用ください。