I am looking to be able to click a button, which dismisses the keyboard, and replace the keyboard space with a new view. Notion has this functionality in their app. I've attached a gif for clarity on what functionality I'm trying to achieve.
You can get the height of the keyboard with
.onReceive(NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.compactMap { $0.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue }
.map { $0.cgRectValue.height }, perform: { height in
self.height = height //Adjust the height based on the keyboard
})
Then bring the keyboard in/out by setting
@FocusState var isFocused: Bool
to true
/false
Here is a full sample.
import SwiftUI
struct KeyboardHeightView: View {
//Use this to bring/dismiss keyboard
@FocusState var isFocused: Bool
@State private var height: CGFloat = 300
@State private var text: String = "test"
@ScaledMetric var buttonHeight = 40
var body: some View {
VStack{
TextEditor(text: $text)
.focused($isFocused)
//Parent for buttons and actions
Rectangle()
.fill(Color.white)
.border(Color.green)
.overlay {
//Area for buttons and actions
VStack {
//Space for the buttons
HStack{
Text("tap to dismiss")
.onTapGesture {
isFocused = false //Dismiss Keyboard
}
}
.frame(height: buttonHeight)
.frame(maxWidth: .infinity)
.border(Color.red)
//Space for other actions.
Button("perform some action") {
//Do something
isFocused = true //Show the keyboard again.
}
Spacer()
}
}
.frame(height: height + buttonHeight) //Keyboard + the space for the buttons that dismiss keyboard and show actions
}.ignoresSafeArea(.keyboard)
.edgesIgnoringSafeArea(.bottom)
.onReceive(NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.compactMap { $0.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue }
.map { $0.cgRectValue.height }, perform: { height in
self.height = height //Adjust the height based on the keyboard
})
.task {
isFocused = true //Show keyboard when the View appears
}
}
}
#Preview {
KeyboardHeightView()
}