📘
[SwiftUI]TextFieldで編集状態を変更する
iOSのSwiftUIでTextFieldの編集状態によって、Viewの出しわけをしたい時があります。
例えば、編集中は下部のボタンを非表示にしたい場合などです。
TextFieldで編集状態を検知する
SwiftUIのTextField
の定義は以下のようになっています。
init<S>(_ title: S, text: Binding<String>, onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void = {}) where S : StringProtocol
編集状態の検知はonEditingChanged
で行います。
struct ContentView: View {
@State var text: String = ""
@State var editing: Bool = false
var body: some View {
VStack(spacing: 16.0) {
TextField.init("enter text", text: self.$text, onEditingChanged: { editingChanged in
debugPrint("onEditingChanged:\(editingChanged)")
self.editing = editingChanged
})
if self.editing {
Text("editing")
}
Spacer()
}.padding()
.contentShape(RoundedRectangle(cornerRadius: 0.0))
.onTapGesture {
debugPrint("onTap")
UIApplication.shared.endEditing()
}
}
}
extension UIApplication {
func endEditing() {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
onEditingChanged
で受け取った値を@State var editing: Bool
に渡して、テキストの出しわけをしています。
TextFieldのフォーカスを外す方法
現在、標準でフォーカスを外す方法はiOSには備わっておりません。(watchOS/tvOSにはあります)
フォーカスを外すには以下のようにUIKit
を使用します。
struct Content: View {
.....
.contentShape(RoundedRectangle(cornerRadius: 0.0))
.onTapGesture {
debugPrint("onTap")
UIApplication.shared.endEditing()
}
.....
extension UIApplication {
func endEditing() {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
小技ですが、contentShape
を使うことで、タップエリアを広げています。
Discussion