SwiftUI - TextFieldとSecureFieldとTextEditorについて

1. TextField

TextFieldは、ユーザーが文字などを入力できるフォームです。使い方は、下記のように記述すると出力できます。デフォルトでは、スタイルが何も設定されていないのでプレースホルダー(ラベル)だけが表示されます。プレースホルダーも空にしてしまうと、どこに出力されているのかわからなくなります。

@State var name: String = ""

var body: some View {
  TextField("お名前", text: $name)
}

alt

.textFieldStyle(RoundedBorderTextFieldStyle())を追加すると画像のような少し角丸のボーダーで入力フォームが出力されます。

@State var name: String = ""

var body: some View {
  TextField("お名前", text: $name)
  .textFieldStyle(RoundedBorderTextFieldStyle())
  .frame(width: 300)
}

alt

独自にスタイルの指定も可能です。

@State var name: String = ""

var body: some View {
  TextField("お名前", text: $name)
  .padding(8)
  .border(Color(UIColor.separator))
  .background(Color(red: 0, green: 0, blue: 0, opacity: 0.1))
  .frame(width: 300)
}

2. TextFieldを使うときに覚えておきたい設定

TextField使うときに覚えておきたい設定を何個か書いておこうと思います。内容はコメントアウトに記載しています。

keyboardTypeの種類は抜粋したもので、他にも種類があります。気になる方は、Qiitaさんの記事が画像付きでわかりやすいと思います。

//キーボードの指定
.keyboardType(.default)

//.URL - URL入力用
//.numberPad - PIN入力用
//.phonePad - 電話番号用
//.emailAddress - アドレスを入力用
//文字の自動大文字化
.autocapitalization(.none) //.none | .words | .sentences | .allCharacters

//.none - 自動変換なし
//.words - 単語の最初の文字を大文字化
//.sentences - 最初の文字を大文字化
//.allCharacters - すべて大文字化
//入力の自動修正を無効にする設定
.disableAutocorrection(true) // true | false

//true - 無効
//false - 有効
//テキストの配置指定
.multilineTextAlignment(.leading) // .leading | .center | .trailing

//.leading - 左寄せ(デフォルト)
//.center - 中央寄せ
//.trailing - 右寄せ

3. シュミレーターでキーボードが表示されない場合

シュミレーターでキーボードの確認をしようとして、うまくシュミレーターにキーボードが表示されなかった場合は下記のどちらかの方法でキーボードが出現します。

  • シュミレーターのメニューの「I/O > Keyboard > Connect Hardware Keyboard」のチェックを外す。(shift + command + K
  • シュミレーターのメニューの「I/O > Keyboard > Toggle Software Keyboard」のチェックをつける。(command + K

4. SecureField

alt

パスワード入力など文字を見えなくしたいときは、TextFieldではなくSecureFieldを使用すると入力文字を黒い丸にしてくれます。

@State private var password = ""
@State private var username = ""
  
var body: some View {
  Form {
    TextField(
      "アカウント名 または メールアドレス",
      text: $username
    )
    .autocapitalization(.none)
    .disableAutocorrection(true)
    
    SecureField(
      "パスワード",
      text: $password
    )
  }
}

5. TextEditor

文章など複数行の文を入力・表示する場合はTextEditorを使用します。使い方は、TextFieldSecureFieldと同じですが、TextEditorにはプレースホルダーの出力が実装されていないようです。

@State var textEdit: String = ""

var body: some View {
  TextEditor(text: $textEdit)
}

TextEditorの初期値に複数行の文に、改行やダブルクォーテーションを含めたい場合、""" 文章 """のようにダブルクォーテーションx3で囲うことで改行などを含めることができます。

@State var textEdit: String = """
  "こんにちわ"
  
  "こんばんわ"
"""

6. TextEditorのカラー変更

alt

TextEditorの背景色などを変更したい場合は、UITextViewの背景を透明に設定することで背景色が変更可能になります。

//追加
init() {
  UITextView.appearance().backgroundColor = .clear
}

var body: some View {
  TextEditor(text: $textEdit)
    .padding()
    .background(Color(red: 0, green: 0, blue: 0, opacity: 0.1))
    .font(.custom("HelveticaNeue", size: 20))
    .cornerRadius(16)
    .overlay(
      RoundedRectangle(cornerRadius: 16)
      .stroke(Color.black, lineWidth: 4)
    )
    .frame(width: 300, height: 200, alignment: .leading)
}

init() { ... } - 初期化
appearance() - オブジェクトの外観プロキシを返す
.clear - 透明に設定

7. 文字数カウントと文字数制限

alt

Qiitaさんの記事を参考に文字数のカウントや文字数制限を実装してみました。import CombineonReceiveで実装できるようです。

import SwiftUI
import Combine

struct ContentView: View {
  @State var textEdit: String = ""
  
  var body: some View {
    VStack {
    Text(String(textEdit.count))
      
    TextEditor(text: $textEdit)
      .onReceive(Just(textEdit)) { _ in
        if textEdit.count > 140 {
          textEdit = String(textEdit.prefix(140))
        }
      }
      .border(Color(UIColor.separator))
      .frame(width: 300, height: 150, alignment: .leading)
      
    }
  }
}

onReceive - パブリッシャーによって発行されたデータを検出したときに実行するアクションを追加
Just - 各サブスクライバーに1回だけ出力を送信
prefix - コレクションの初期要素を含む、指定された最大長までのサブシーケンスを返す

TextField | Apple Developer Documentation
SecureField | Apple Developer Documentation
Swift-initialization - Dev Guides
onReceive(_:perform:) | Apple Developer Documentation
Just | Apple Developer Documentation
prefix(_:) | Apple Developer Documentation