はじめに
SwiftUIで画面遷移をした際に、キーボードを自動で表示する方法をメモしておきます。
コード
import SwiftUI
struct ContentView: View {
// ContentView ⇄ SecondViewのシートを管理する状態変数
@State var isShowSheet: Bool = false
var body: some View {
VStack{
Button{
isShowSheet.toggle()
}label: {
Text("Go SecondView")
}
}
.sheet(isPresented: $isShowSheet) {
SecondView(isShowSheet: $isShowSheet)
}
}
}
struct SecondView: View {
// フォーカスが当たるTextFieldを、判断するためのenumを作成します。
enum Field: Hashable {
case text
}
// @FocusState変数は、現在フォーカス中か、フォーカスしてないのか(Bool型)の定義ではなく、
// 現在フォーカスしているのが、どのテキストフィールドか(カスタムField型)を定義します。
@FocusState private var focusedField: Field?
// ContentView ⇄ SecondViewのシートを管理する状態変数
@Binding var isShowSheet: Bool
@State private var inputText = ""
var body: some View {
VStack {
TextField("タイトル", text: $inputText)
.padding()
.border(.blue)
.padding()
.focused($focusedField, equals: .text)
}
.onAppear() {
// 画面を表示してから0.5秒後にキーボードを表示
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
focusedField = .text
}
}
}
}
キーボードを閉じる方法については参考サイトを見ていただくと分かるので、割愛します。
参考サイトでは、画面タップ時にキーボードを閉じるようにしていたので、画面表示と共にキーボードを表示するには、Viewが表示された時に、実行するアクションを記述する.onAppearの中に、
focusedField = .titleもしくはfocusedField = .message書けば出来ると考えてやってみましたが、
出来ませんでした。
シート表示だけでなく、NavigationLinkを用いた画面遷移でも同じく出来ませんでした。
詳しくは調べていないのですが、画面遷移時のアニメーションの関係上、画面遷移と同時にキーボードを表示することは出来ないのではないかと講師の方に教えていただきました。
そこで、遅らせて処理を行う(遅延実行)DispatchQueue.main.asyncAfterの中に記述をすると、無事にキーボードを表示する事が出来ました。
キーボードが少し遅れて表示されるので、UI的には美しくないですが、画面遷移する度にTextFieldをタップして、キーボードを表示するという動作がめんどくさく感じていたため、とりあえず良しとします。