SwiftUI キーボードを表示時に特定の View を非表示にする
たとえばこんなコードで ScrollView 内に TextField を置いて、さらにスクロール位置によらないで常に画面下部にある View が表示されるような構成を ZStack で表現すると
import SwiftUI struct ContentView: View { @State private var text: String = "" let bottomBoxHeight: CGFloat = 150 var body: some View { ZStack { ScrollView(.vertical, showsIndicators: true) { VStack { ForEach(0..<20) { (i) in TextField("Textfield\(i)", text: $text) .padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 33)) .overlay( RoundedRectangle(cornerRadius: 30) .stroke(Color(.systemGray3), lineWidth: 1) ) Spacer() .frame(height: 10) } Spacer() .frame(height: bottomBoxHeight) }.padding() } VStack { Spacer() Group { Text("Bottom box") .font(.headline) .foregroundColor(.white) } .frame(minWidth: 0, idealWidth: .infinity, maxWidth: .infinity, minHeight: 0, idealHeight: bottomBoxHeight, maxHeight: bottomBoxHeight, alignment: .center) .background(Color(.red)) } } } }
こういうふうに TextField のキーボードを開いた時に、キーボード上に View が重なってしまい、TextField が見えなくなってしまう。(入力できない)
キーボードを表示した時に特定の View を非表示にできれば解決しそう、と考えて調べてみると
KeyboardObserving というライブラリがあり、これを使って対応できた。
https://github.com/nickffox/KeyboardObserving
使い方は、まずアプリのエントリで最初の View を表示する部分のコードで .environmentObject(Keyboard())
を追加する。
(これをしないと、このあと追加するコードでクラッシュする)
import SwiftUI import KeyboardObserving @main struct SwiftUIHideOnKeyboardSampleAppApp: App { var body: some Scene { WindowGroup { ContentView() .environmentObject(Keyboard()) // これを追加 } } }
あとは問題が起きている View に以下を追加する。
ScrollView(.vertical, showsIndicators: true) { KeyboardObservingView { // KeyboardObservingView にキーボード表示を監視したい View を追加する VStack { // .... 中略 .... }.padding() } } // .... 中略 .... VStack { // .... 中略 .... } .hideOnKeyboard() // キーボードを表示した時に非表示にしたい View に .hideOnKeyboard() を追加する
これでキーボード表示時に、TextField が隠されることは無くなった。
今回の記事の完全なコードは GitHub にある。
https://github.com/daisuke-t-jp/SwiftUIHideOnKeyboardSampleApp