TextField は編集可能なテキストインターフェースを表示し、ユーザーからの入力を受け付けることができます。
今回は、TextField の使用方法について説明します。
OS: macOS Big Sur 11.2.1
Xcode: 12.4
Swift: 5.2.4
TextField の基本的な構文は以下の通りです。
第1引数には、入力欄が空の場合に表示される文字列(※)を指定し、第2引数には入力された文字列を格納するための String 型変数を指定します。この String 型の変数は @State 等で宣言をしておく必要があります。また 第2引数の変数の先頭には $ を付けて参照渡しにして、TextField がプロパティ値を更新できるようにしておきます。
※この文字列のことをプレースホルダと呼びます。
TextField("プレースホルダ", text: $value)
以下にコード例を示します。
このコードでは、入力欄に「氏名を入力」と表示し、入力された文字列は変数 value に書くのいうされます。
struct ContentView: View {
@State private var value: String = ""
var body: some View {
TextField("氏名を入力", text: $value)
}
}
実行すると、下図のようにプレースホルダに「氏名を入力」が表示され、テキストを入力できるようになります。ただし枠線がないため、どこからどこまでが入力範囲なのかわかりません。
枠線を付けるには textFieldStyle() モディファイアを使用します。
以下のスタイルを使用することができます。
コード例を以下に示します。
struct ContentView: View {
@State private var value1: String = ""
@State private var value2: String = ""
@State private var value3: String = ""
var body: some View {
VStack {
TextField("DefaultTextFieldStyle", text: $value1)
.textFieldStyle(DefaultTextFieldStyle())
.padding()
TextField("PlainTextFieldStyle", text: $value2)
.textFieldStyle(PlainTextFieldStyle())
.padding()
TextField("RoundedBorderTextFieldStyle", text: $value3)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
}
}
先程の例では、1つずつスタイルを適用しましたが、一度に複数の TextField に適用することもできます。
以下に例を示します。
3つの TextField が VStack に内包されています。この VStack に対し、モディファイア textFieldStyle を適用することで、全ての TextField にスタイルが設定されます。
struct ContentView: View {
@State private var value1: String = ""
@State private var value2: String = ""
@State private var value3: String = ""
var body: some View {
VStack {
TextField("TextField 1", text: $value1)
TextField("TextField 2", text: $value2)
TextField("TextField 3", text: $value3)
}
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
}
TextField に入力された内容が、変数に格納されているかを確認するために Text に表示してみましょう。
以下にコード例を示します。
@State を付けた変数は、内容が変更された場合は即時ビューに反映されます。
Text の引数には「(“\name”)」を渡していますので、TextField に入力した内容がそのまま表示されます。
struct ContentView: View {
@State private var name: String = ""
var body: some View {
VStack {
TextField("氏名を入力", text: $name)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Text("\(name)")
}
}
}
TextField の以下の書式を使用すると、「入力が開始された」と「入力が終了した」ということを判断して処理をすることができます。
第3引数の onEditingChanged は、ユーザーがテキストの「入力うを開始したとき」と「入力を終了したとき」に実行されます。onEditinggChanged のクロージャは編集ステータスを示すブール値を受け取ります。ユーザーが編集を開始した時は true、編集を終了した時は false です。
第4引数の onCommit は、TextField にフォーカスがある状態で、ユーザーがアクション(たとえば Return キーを押したとき)をしたときに実行されます
init<s>(
_ title: S,
text: Binding,
onEditingChanged: @escaping (Bool) -> Void = { _ in },
onCommit: @escaping () -> Void = {}
) where S : StringProtocol
以下にコード例を示します。
この例は、TextField で入力が開始されると Text に「入力中」を表示します。また未入力の時は「未入力」を表示します。リターンキーを押した場合は入力が完了しますので、入力された文字列を使用して「こんにちは、○○さん」というメッセージを表示します。
struct ContentView: View {
@State private var name = ""
@State private var message = ""
@State private var status = "未入力"
var body: some View {
VStack {
TextField(
"名前を入力して下さい",
text: $name
onEditingChanged: { isEditing in
if isEditing {
self.status = "入力中"
} else {
self.status = "未入力"
}
},
/// リターンキーが押された時の処理
onCommit: {
if self.name.count == 0 {
self.message = ""
} else {
self.message = "こんにちは、\(self.name)さん"
}
self.name = "" // リターンキーが押された後、TextField を空にする
})
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Text(status) // 入力状態を表示
Text(message) // メッセージを表示
}
}
}
TextField の第3引数の onEditingChanged はクロージャの先頭で「isEditing in」と記述しています。この変数「isEditing」は任意の名前で構いません。入力中の時は true が代入されます。
よって次の if 文で isEditing が true かfalse かを判断して、入力中の処理と未入力時の処理を記載しています。
続いて、第4引数の onCommit は、前述したように TextField でリターンキーが押されたときに実施されます。
if 文で、入力された文字列をカウントし、1文字も入力されていない場合は、変数 name を空にし、1文字以上入力されている場合は「こんにちは○○さん」を表示します。
TextFieldに文字列を入力する際、.keyboardType モディファイアを使用して、表示するキーボードを指定することができます。
.keyboardType の引数には、以下に示す UIKeyboardType 列挙体の値を指定することができます。
コード例を以下に示します。
この例では数字を入力するキーボードを表示します。
struct ContentView: View {
@State var numberString = ""
var body: some View {
TextField("数字を入力", text: $numberString)
.keyboardType(.decimalPad)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
}
autocapitalization モディファイアを使用雨すると、アルファベット入力時の大文字入力変換を制御できます。
引数には、以下に示す UITextAutocapitalizationType 列挙体の値を指定することができます。
コード例を以下に示します。
この例では全ての入力文字を自動で大文字にします。
struct ContentView: View {
@State var alphabetString = ""
var body: some View {
TextField("アルファベットを入力", text: $alphabetString)
.keyboardType(.asciiCapable)
.autocapitalization(.allCharacters)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
}
テキストを左寄せ、中央寄せ、右寄せのいずれかにするには、multilineTextAlignment を使用します。
引数には、以下に示す TextAlignment 列挙体の値を指定することができます。
コード例を以下に示します。
struct ContentView: View {
@State var strVal1 = ""
@State var strVal2 = ""
@State var strVal3 = ""
var body: some View {
VStack {
TextField("左寄せ", text: $strVal1)
.multilineTextAlignment(.leading)
TextField("中央寄せ", text: $strVal2)
.multilineTextAlignment(.center)
TextField("右寄せ", text: $strVal3)
.multilineTextAlignment(.trailing)
}
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
}
TextField は様々なモディファイアがありカスタマイズすることができます。
ぜひご自身のアプリに合わせて、モディファイアを使用してみてください。