SwiftUIでテキストの入力といえばTextfieldがよく使われていると思いますが、複数行のテキストの入力にはTextEditorが便利です。
iOS14から使えます。
開発環境 | バージョン |
---|---|
Xcode | 12.5.1 |
iOS | 14.0以降 |
macOS | BigSur 11.5.2 |
文字数制限付き・キーボードを閉じるボタン付きのTextEditor
TextEditorは複数行の長いテキストを入力できますが、そのままだと文字数制限機能はなく、入力後キーボードを閉じる機能もありません。
(Enterを押してもひたすら改行されるだけで、入力完了できないっていうのは地味に困るのです。)
ということで、200文字まで入力・カウントできて、入力後キーボードを閉じられるテキストボックスを作ってみました。
入力完了を押すとキーボードが閉じます。
//
// ContentView.swift
// TextEditorApp
//
// Created by Yaguchi Sato on 2021/12/10.
//
import SwiftUI
struct ContentView: View {
@State private var note = ""
//入力文字数
@State private var totalChars = 0
@State private var notecount = ""
var body: some View {
VStack {
HStack {
//入力文字数の表示
Text(" \(totalChars) / 200")
Spacer()
}
ZStack(alignment: .topLeading ){
//Textの入力 文字カウントと文字数制限付き
TextEditor(text: $note)
.onChange(of: note, perform: {notecount in totalChars = note.count
})
//200文字以上になったら最後の文字を削除することで制限
.onChange(of: note, perform: { value in
if value.count > 200 {
note.removeLast(note.count - 200)
}
})
//入力欄の外枠 角丸四角・背景透過・縁枠グレー
RoundedRectangle(cornerRadius: 8.0)
.strokeBorder(Color.gray.opacity(0.5), lineWidth: 0.3).background(Color.clear)
}.frame(height: 300, alignment: .center)
//入力完了ボタンでendEditを呼び出す
Button(action:{
UIApplication.shared.endEdit()
}){Text("入力完了")
.font(.title)
.padding(8)
.foregroundColor(.white)
.background(Color.orange)
.cornerRadius(10)
}
}.padding()
}
}
//キーボードを閉じる処理 UIApplicationを拡張
extension UIApplication{
func endEdit(){
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
TextEditorにはTextFieldStyleのように入力枠スタイルの設定項目がないので、自分で角丸四角とZStackで重ねて、.frameでサイズ指定してます。
.onChangeで値の変更を検知。2つ重ねてもちゃんと機能しました。
ちなみに行数制限したい時は、
TextEditor().lineLimit(5)
というように()内に行数上限を指定するとできます。
キーボードを閉じる処理はUIApplicationを利用してます。
そのうちアップデートされる気はしますが、いまのところはこんな感じで対処できました。以上。