この記事では、TextEditorの実装方法について徹底解説していきたいと思います。
Contents
TextEditorとは?
TextEditorは、2行以上のテキスト表示したり、入力させたりするオブジェクトです。エリア内でスクロールできるため、長文を表示させることが可能です。

このようなオブジェクトのことです。
実装方法は簡単で、@StateのString型の変数を用意して、TextEditor(text: $text)と記載するだけで実装できます。
TextEditorのスタイル
シンプル

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.padding()
}
}
枠線をつける

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.border(.gray, width: 1)
.padding()
}
}
.border(.gray, width: 1)で、色と枠線の太さが指定できます。
枠線を丸くする

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.overlay(RoundedRectangle(cornerRadius: 5).stroke(.gray, lineWidth: 1))
.padding()
}
}
枠線を丸くする場合は、.overlay(RoundedRectangleを使って実装します。
cornerRadius: 5で、枠線の丸みが変えられます。
.stroke(.gray, lineWidth: 1))で、色と枠線の太さが変えられます。
幅と高さを変える

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.border(.gray, width: 1)
.frame(width: 150, height: 150)
.padding()
}
}
※わかりやすいように枠線をつけてます。
.frame(width: 150, height: 150)で高さと幅を指定できます。
文字の大きさと色を変更

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.font(.largeTitle)
.foregroundColor(.red)
.padding()
}
}
Textと同様.fontで大きさとフォントを変更できます。
.foregroundColorで文字色が変更できます。
テキストの位置を変える

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.multilineTextAlignment(.center)
.border(.gray)
.padding()
}
}
※わかりやすいように枠線をつけてます。
テキストの行間を変える

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.lineSpacing(30)
.border(.gray)
.padding()
}
}
※わかりやすいように枠線をつけてます。
影をつける

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.border(.gray)
.shadow(color: .gray, radius: 10, x: 10, y: 10)
.padding()
}
}
※わかりやすいように枠線をつけてます。
背景色を変更する

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.border(.gray)
.background(.green)
.padding()
.onAppear() {
UITextView.appearance().backgroundColor = .clear
}
.onDisappear() {
UITextView.appearance().backgroundColor = nil
}
}
}
.background(.green)をつけるだけで良いように思えますが、UITextViewの背景色で上書き?されるので、それだけでは背景色を変更できません。
そのため、一旦UITextViewの背景色を透明にしてから、.background(.green)を設定する必要があります。
ということで、以下の3行で、UITextViewの背景色を透明にします。
.onAppear() {
UITextView.appearance().backgroundColor = .clear
}
その後で、.background(.green)が呼ばれるので緑色になるということです。
で、念の為、透明にした背景色をnilに戻しておきます。
.onDisappear() {
UITextView.appearance().backgroundColor = nil
}
TextFieldの制御
アルファベットの自動大文字変換をオフにする

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.autocapitalization(.none)
.border(.gray)
.padding()
}
}
※わかりやすいように枠線をつけてます。
自動的に、最初の単語は大文字に変換されてしまいます。それをこちらのコードで無効にすることができます。
単語の自動修正をオフにする

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.disableAutocorrection(true)
.border(.gray)
.padding()
}
}
※わかりやすいように枠線をつけてます。
間違えた単語を打つと、確定した時に自動で単語に変換されますが、.disableAutocorrection(true)にすると、変換されなくなります。
案外、自分の名前とかを打つとき、自動変換が邪魔になる時があるので、結構この指定は使うかもしれません。
キーボードタイプ

struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.keyboardType(.emailAddress)
.border(.gray)
.padding()
}
}
※わかりやすいように枠線をつけてます。
.keyboardType(.emailAddress)でキーボードのタイプを指定できます。12種類あります。
| タイプ | 説明 |
|---|---|
.default |
デフォルト(指定なしだとこれになる) |
.asciiCapable |
ASCII |
.numbersAndPunctuation |
数字と句読点 |
.URL |
URL |
.numberPad |
PIN入力用のテンキー |
.phonePad |
電話番号 |
.namePhonePad |
人の名前や電話番号を入力するためのキーパッド |
.emailAddress |
メールアドレス |
.decimalPad |
数字と小数点 |
.twitter |
Twitterのテキスト入力用 |
.webSearch |
Web検索用語やURL入力用 |
.asciiCapableNumberPad |
ASCIIの数字のみを出力するナンバーパッド |
ただ、キーボードのタイプを変えたからと言って、そのキーボードにあるキーしか打たれないということはありません。なぜなら、コピペができるからです。
書き込めなくする
ただ単に表示したいだけというときは、以下のように.disabled(true)をつけると編集できなくなります。falseで書き込めるようになります。
struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.frame(height: 180)
.border(.gray)
.disabled(true)
.padding()
}
}
イベントを取得
タップされたとき
以下のコードでTextFieldをタップした時のイベントが取得できます。
struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.onTapGesture() {
print("タップされたよ")
}
}
}
値が変わったとき
入力されるたびに、.onChangeが呼ばれます。
struct ContentView: View {
@State var inputText = ""
var body: some View {
TextEditor(text: $inputText)
.onChange(of: inputText) { newValue in
print("入力された値:\(newValue)")
}
}
}
プレースホルダーを自作する
TextFieldにはあって、TextEditorにないもの。それはプレースホルダーです。
プレースホルダーというのは、TextEditorやTextFieldで何も文字が入力されていないときに、入力する内容のヒントを書くためのものです。以下の画像のようにグレーで薄く文字が表示されます。文字を入力すると消えます。
このプレースホルダーですが、TextFieldはプレースホルダーを設定できるのですが、TextEditorは設定できません。そのため自作しなければなりません。

struct ContentView: View {
@State private var inputText = ""
var body: some View {
ZStack(alignment: .topLeading) {
TextEditor(text: $inputText)
.border(.gray)
.frame(height: 180)
.padding()
if inputText.isEmpty {
Text("ここに文字を入力してください。")
.foregroundColor(Color(uiColor: .placeholderText))
.allowsHitTesting(false)
.padding(20)
.padding(.top, 5)
}
}
}
}
実装方法は単純で、TextEditor内の文字が入力されていない場合、TextEditorの上にグレーの文字を配置するという内容です。
まず、重ねるのでZStackを使い、左上に揃えます。
ZStack(alignment: .topLeading) {
もし、inputTextが空文字の場合は、Textを表示します。
if inputText.isEmpty {
Text("ここに文字を入力してください。")
Textを重ねているので、プレースホルダー部分のTextをタップすると、TextEditorがタップされなくなりカーソルが合わなくなります。
そのため、以下の指定をしてTextを触ってもTextEditorが反応するようにします。
.allowsHitTesting(false)
あとは、.paddingでちょうど良い場所に調整するだけです。
.padding(20) .padding(.top, 5)
TextEditorのプレースホルダーに関する記事は色々とあるので、自分に合ったプレースホルダーの実装をしてみてください。
参考 【SwiftUI】TextEditorにプレースホルダーを表示するQiita 参考 SwiftUI TextEditor にプレースホルダーを設定するGitHub 参考 SwiftUIのTextEditorでもプレースホルダーを使いたいLento con forza参考文献

