I have seven TextField
inside my main ContentView
. When user open keyboard some of the TextField
are hidden under the keyboard frame. So I want to move all TextField
up respectively when the keyboard has appeared.
I have used the below code to add TextField
on the screen.
struct ContentView : View {
@State var textfieldText: String = ""
var body: some View {
VStack {
TextField($textfieldText, placeholder: Text("TextField1"))
TextField($textfieldText, placeholder: Text("TextField2"))
TextField($textfieldText, placeholder: Text("TextField3"))
TextField($textfieldText, placeholder: Text("TextField4"))
TextField($textfieldText, placeholder: Text("TextField5"))
TextField($textfieldText, placeholder: Text("TextField6"))
TextField($textfieldText, placeholder: Text("TextField6"))
TextField($textfieldText, placeholder: Text("TextField7"))
}
}
}
Output:
I have created a really simple to use view modifier.
Add a Swift file with the code below and simply add this modifier to your views:
The most elegant answer I've managed to this is similar to rraphael's solution. Create a class to listen for keyboard events. Instead of using the keyboard size to modify padding though, return a negative value of the keyboard size, and use the .offset(y:) modifier to adjust the the outer most view containers's offset. It animates well enough, and works with any view.
I used Benjamin Kindle's answer as as starting point, but I had a few issues I wanted to address.
keyboardWillChangeFrameNotification
to the list of notifications processed addresses this.init
function that accepts a@ViewBuilder
so that you can use theKeyboardHost
view like any other View and simply pass your content in a trailing closure, as opposed to passing the content view as a parameter toinit
.Rectangle
for adjusting the bottom padding.UIWindow
asUIWindow.keyboardFrameEndUserInfoKey
.Pulling that all together I have:
I'm not sure if the transition / animation API for SwiftUI is complete, but you could use
CGAffineTransform
with.transformEffect
Create an observable keyboard object with a published property like this:
then you could use that property to rearrange your view like this:
or simpler