Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 14 SwiftUI Keyboard lifts view automatically

I am using TextField in my view and when it becomes the first responder, it lefts the view as shown in the below GIF.

Is there any way I can get rid of this behavior?

enter image description here

Here is my code

NavigationView(content: {
    ZStack{
        MyTabView(selectedIndex: self.$index)
            .view(item: self.item1) {
                NewView(title: "Hello1").navigationBarTitle("")
                    .navigationBarHidden(true)
            }
            .view(item: self.item2) {
                NewView(title: "Hello2").navigationBarTitle("")
                    .navigationBarHidden(true)
            }
            .view(item: self.item3) {
                NewView(title: "Hello3").navigationBarTitle("")
                    .navigationBarHidden(true)
            }
    }.navigationBarHidden(true)
    .navigationBarTitle("")
}).ignoresSafeArea(.keyboard, edges: .bottom)

// New View

struct NewView:View {
    @State var text:String = ""
    var title:String
    var body: some View {
        VStack {
            Spacer()
            Text("Hello")
            TextField(title, text: self.$text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
        }.padding()
        .onAppear {
            debugPrint("OnApper \(self.title)")
        }
    }
}
like image 279
Malav Soni Avatar asked Sep 18 '20 15:09

Malav Soni


People also ask

How do I stop SwiftUI keyboard from pushing up the view?

Editing answer to remove GeometryReader. I tried running it without GeometryReader on empty project and it worked.

How do I move view up when keyboard appears in iOS SwiftUI?

Moving SwiftUI View Up When Keyboard Appears Create keyboard height state. SwiftUI will automatically update the view whenever the keyboard height changes. Add padding to the bottom of the view, which will make it move up and down with the keyboard.

How do I hide the keyboard in SwiftUI?

You can now write hideKeyboard() from inside any SwiftUI view. Important: If you're using Xcode 12 you need to use RoundedBorderTextFieldStyle() rather than . roundedBorder .


3 Answers

For .ignoresSafeArea to work you need to fill all the available area (eg. by using a Spacer).


The following will not work (no Spacers, just a TextField):

struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        VStack {
            TextField("asd", text: self.$text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }
        .ignoresSafeArea(.keyboard, edges: .bottom)
    }
}

However, it will work when you add Spacers (fill all the available space):

struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        VStack {
            Spacer()
            TextField("asd", text: self.$text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            Spacer()
        }
        .ignoresSafeArea(.keyboard, edges: .bottom)
    }
}

If you don't want to use Spacers you can also use a GeometryReader:

struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        GeometryReader { _ in
            ...
        }
        .ignoresSafeArea(.keyboard, edges: .bottom)
    }
}
like image 152
pawello2222 Avatar answered Oct 28 '22 10:10

pawello2222


You should apply the modifier on the ZStack, NOT the NavigationView

NavigationView(content: {
    ZStack{
        ,,,
    }.navigationBarHidden(true)
    .navigationBarTitle("")
    .ignoresSafeArea(.keyboard, edges: .bottom) // <- This line moved up
})

Full working example:

struct ContentView: View {
    @State var text = ""
    var body: some View {
        VStack{
            Spacer()
            Text("Hello, World")
            TextField("Tap to test keyboard ignoring", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }
        .padding()
        .ignoresSafeArea(.keyboard, edges: .bottom)
    }
}

Demo

like image 16
Mojtaba Hosseini Avatar answered Oct 28 '22 11:10

Mojtaba Hosseini


What eventually worked for me, combining answers posted here and considering also this question, is the following (Xcode 12.4, iOS 14.4):

GeometryReader { _ in
    VStack {
        Spacer()
        TextField("Type something...", text: $value)
        Spacer()
    }.ignoresSafeArea(.keyboard, edges: .bottom)
}

Both spacers are there to center vertically the textfield.

Using only the GeometryReader or the ignoresSafeArea modifier didn't do the trick, but after putting them all together as shown above stopped eventually the view from moving up upon keyboard appearance.

like image 6
Gabb Avatar answered Oct 28 '22 12:10

Gabb