SwiftUI iOS14 - Disable keyboard avoidance
Asked Answered
N

3

19

Is there a way to disable the native keyboard avoidance on iOS14?

There is no keyboard avoidance in iOS13, so I want to implement my own, but when I do the native one on iOS14 is still active, so both my implementation and the native one run at the same time, which I don't want.

My deployment target is iOS13, so I need a solution for both iOS13 and iOS14.

Nymphalid answered 13/1, 2021 at 11:29 Comment(4)
Does this answer your question? iOS 14 SwiftUI Keyboard lifts view automaticallyDinnage
No, I need it to work on iOS 13 alsoNymphalid
There is no keyboard avoidance on iOS 13. And the above solution won't do anything on iOS 13, so it should work with your code.Dinnage
As I sad, I have written my own keyboard avoidance logic (which works on iOS 13), but I need to turn of the iOS 14 native keyboard avoidanceNymphalid
D
26

You can use if #available(iOS 14.0, *) if you want to adapt the iOS 14 code so it compiles on iOS 13.

Here is an adapted version of this answer to work on both iOS 13 and iOS 14:

struct ContentView: View {
    @State var text: String = ""

    var body: some View {
        if #available(iOS 14.0, *) {
            VStack {
                content
            }
            .ignoresSafeArea(.keyboard, edges: .bottom)
        } else {
            VStack {
                content
            }
        }
    }

    @ViewBuilder
    var content: some View {
        Spacer()
        TextField("asd", text: self.$text)
            .textFieldStyle(RoundedBorderTextFieldStyle())
        Spacer()
    }
}
Dinnage answered 13/1, 2021 at 16:10 Comment(2)
For me, using iOS 13.2, I had to use .all instead of .bottom. Either way, thanks for posting an answer to this.Jehial
Maybe for simple views like this (filled with just spacers) this works. But there may be a case when you have a complex view, with custom header and many texts/buttons/textfields. In that case the view might still get pushed up, despite using .ignoreSafeArea modifier, so the solution to that would be to embed your view in GeometryReader and add the modifier to it instead of the formerAguayo
B
10

If you're still having issues with content being pushed around by the keyboard, Levan's comment solved this for me.

Re-posting as an answer so it's easier to find.

var body: some View {
    GeometryReader { _ in
        VStack {
            //content
        }
        .sheet(isPresented: $showModal) {
            ModalWithTextFieldThatPushesUpParentContent()
        }
    }
    .ignoresSafeArea(.keyboard) //keyboard avoidance
}

This is especially annoying when a Sheet view has a textfield and the keyboard pushes the parent content up.

  1. Need to add the ignore code to the parent view
  2. Add a GeometryReader, even if you're not using it
  3. If you are using a NavigationStack the GeometryReader needs to be inside the NavigationStack
Bankruptcy answered 2/9, 2023 at 17:3 Comment(0)
C
0

I wanted to come add some additional context to this. I have a TabView, that has NavigationStack contained within it. I created a custom TabBar and it was being displaced by the keyboard. All attempts to use .ignoresSafeArea(...) failed to work for the most part, until I realized that I needed to use it DIRECTLY on my TabView. I had to do this specifically because I had created that TabBar. I was able to get it working by using the following on iOS 14+.

TabView {...}
    .ignoresSafeArea(.keyboard, edges: .bottom)
    .safeAreaInset(edge: .bottom, content: { TabBar(...) }

Note:

  • This does not affect @FocusState displacement. I verified that displacement still worked despite children views of that TabView containing displaceable content.
Cosetta answered 25/6, 2024 at 5:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.