iOS13 saw TextField not having any sort of keyboard avoidance handling in place. As such, we created our how keyboard avoidance mechanism which works well. We upgraded to iOS14 and this resulted in TextFields having keyboard avoidance built in. However, the keyboard avoidance does not seem to work as expected.
Issue 1 The first issue we experienced was keyboard avoidance not working expected for TextFields in and around the centre of the screen. Given this code:
struct ContentView: View {
@State var text:String = ""
var body: some View {
TextField("Testing", text: $text)
}
}
On an and iPhone 8 Plus the Textfield is moved up. In our opinion this shouldn't be happening as the TextField will not be hidden by the keyboard and as such it should remain in the same place.
Question 1: Is this a bug and should it be reported to Apple? We believe this to be a bug / issue.
We have found that using the following:
struct ContentView: View {
@State var text:String = ""
var body: some View {
VStack {
Spacer()
TextField("Testing", text: $text)
}
}
}
The TextField will be moved just above the keyboard. Which is the expected behaviour. We've also found that with the code below:
struct ContentView: View {
@State var text:String = ""
var body: some View {
VStack {
TextField("Testing", text: $text)
Spacer()
}
}
}
The TextField is not moved as it would never be covered by the TextField. Once again, this is the behaviour we expect. However, any TextField in and around the centre of the screen it would seem that the keyboard avoidance moves the TextField in scenario's where it shouldn't.
Issue 2
Our app holds TextFields in and around the centre on certain screens and as such the issue discovered above simply adds to a poor user experience and so we looked to "switch off" this keyboard avoidance provided to us. We looked to use the ignoresSafeArea
modifier as follows:
struct ContentView: View {
@State var text:String = ""
var body: some View {
if #available(iOS 14.0, *) {
VStack {
TextField("Testing", text: $text)
}
.ignoresSafeArea(.keyboard, edges: .bottom)
} else {
// Fallback on earlier versions
// Our iOS13 Code
}
}
}
The observed result is that the modifier simply doesn't work. The TextField is still moved upwards. However when using something like this:
struct ContentView: View {
@State var text:String = ""
var body: some View {
if #available(iOS 14.0, *) {
VStack {
Spacer()
TextField("Testing", text: $text)
}
.ignoresSafeArea(.keyboard, edges: .bottom)
} else {
// Fallback on earlier versions
// Our iOS13 Code
}
}
}
the ignoresSafeArea
works and so this leads to the second question:
Question 2
Is there are bug with the ignoresSafeArea
modifier as well? Is this something that should be reported?
It would seem that there is an underlying issue with TextFields in and around the centre of the screen?
Question 3 Anyone know of ways around these issues? Because right now it's a huge problem on iOS14. The keyboard avoidance doesn't work and any attempt to try and switch it off doesn't work either.
We are using Xcode 12.0 (12A7209)
Update
We have found that wrapping the TextField in a Geometry Reader that this seems to "switch off" Keyboard Avoidance for a TextField. However, we believe this to be a delightful hack that fixes the problem in one way but then also exposes that Keyboard Avoidance doesn't work in Geometry readers which could be a bug / issue for other people...
struct ContentView: View {
@State var text:String = ""
var body: some View {
if #available(iOS 14.0, *) {
GeometryReader { _ in
VStack {
Spacer().frame(height:500) //Compensate for other Views in the Stack
TextField("Testing", text: $text)
}
}
} else {
// Fallback on earlier versions
// Our iOS13 Code
}
}
}