skip to Main Content

I am a beginner coder. I develop my very first app using SwiftUI and I have a huge problem(bug) with keyboard: the View is moving up when TextField is touched. I don’t want my View to move at all.

I have a ContentView(the one with the problem), that contains custom Navigation Bar and several Views.

Simplified code below.

My ContentView:

struct ContentView: View {
    var body: some View {
        
        CustomNavBarContainerPreview {
            
            ZStack {
                Color(.purple)
                    .opacity(0.4)
                    .ignoresSafeArea(.all)
                
                VStack(alignment: .center) {
                    //view with textfield
                    PullView()
                    
                    RandomView()
                    
                    LanguageView()
                    
                    Button {
                        //action
                    } label: {
                        ZStack {
                            RoundedRectangle(cornerRadius: 15)
                                .foregroundColor(.cyan)
                                .frame(minWidth: 300, idealWidth: 340, maxWidth: 340, minHeight: 70, idealHeight: 85, maxHeight: 85, alignment: .center)
                            Text("Accept Settings")
                                .font(Font.custom("Ubuntu-Regular", size: 24))
                                .foregroundColor(.white)
                        }
                        .padding(.vertical, 10)
                    }

                }
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                //using this isn't prevent the view from pusing up
                .ignoresSafeArea(.keyboard, edges: .bottom)
            }
            // it doesn't work too
            .ignoresSafeArea(.keyboard)
            .onTapGesture {
                dismissKeyboard()
            }
            
        }

    }
    
    func dismissKeyboard() {
        UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.endEditing(true)
    }
}

My SubViews:

struct PullView: View {
    
    @State var num1: String = ""
    @State var num2: String = ""
    
    var body: some View {
        
        ZStack(alignment: .topLeading) {
            Rectangle()
                .frame(minWidth: 342, idealWidth: 342, maxWidth: 342, minHeight: 150, idealHeight: 178, maxHeight: 178, alignment: .center)
                .foregroundColor(.white)
            
            VStack {
                HStack {
                    Text("Title One")
                        .bold()
                        .multilineTextAlignment(.leading)
                        .foregroundColor(.black)
                        .padding(.leading, 15)
                    
                    Spacer()
                    
                    Image(systemName: "info.circle.fill")
                        .scaledToFill()
                        .frame(alignment: .trailing)
                        .padding(.trailing, 15)
                    
                }
                .frame(maxWidth: 342, maxHeight: 50)
                .padding(EdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0))
                .background(Rectangle()
                    .foregroundColor(Color(red: 230/255, green: 234/255, blue: 242/255))
                    .opacity(0.5))
                
                HStack(alignment: .center) {
                    
                    Text("field1")
                        .foregroundColor(.black)
                    
                    TextField("", value: $num1, formatter: NumberFormatter())
                        .textFieldStyle(DefaultTextFieldStyle())
                        .foregroundColor(.black)
                        .multilineTextAlignment(.center)
                        .frame(width: 90, height: 48)
                        .keyboardType(.numberPad)
                        .background(.green)
                    
                    Text("field2")
                        .foregroundColor(.black)
                    
                    TextField("", value: $num2, formatter: NumberFormatter())
                        .textFieldStyle(DefaultTextFieldStyle())
                        .foregroundColor(.black)
                        .multilineTextAlignment(.center)
                        .frame(width: 90, height: 48)
                        .keyboardType(.numberPad)
                        .background(.green)
                }
                .padding(.all, 10)
                
                
            }
        }
       
    }
}


struct RandomView: View {
    var body: some View {
        
        ZStack(alignment: .topLeading) {
            Rectangle()
                .frame(minWidth: 342, idealWidth: 342, maxWidth: 342, minHeight: 150, idealHeight: 178, maxHeight: 178, alignment: .center)
                .foregroundColor(.white)
            
            VStack {
                HStack {
                    Text("Title Two")
                        .bold()
                        .multilineTextAlignment(.leading)
                        .foregroundColor(.black)
                        .padding(.leading, 15)
                    
                    Spacer()
                    
                    Image(systemName: "info.circle.fill")
                        .scaledToFill()
                        .frame(alignment: .trailing)
                        .padding(.trailing, 15)
                    
                }
                .frame(maxWidth: 342, maxHeight: 50)
                .padding(EdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0))
                .background(Rectangle()
                    .foregroundColor(Color(red: 230/255, green: 234/255, blue: 242/255))
                    .opacity(0.5))
                
                Text("Random settings")
                Text("Subview test")
                
            }
        }
    }
}

struct LanguageView: View {
    var body: some View {
        
        ZStack(alignment: .topLeading) {
            Rectangle()
                .frame(minWidth: 342, idealWidth: 342, maxWidth: 342, minHeight: 150, idealHeight: 178, maxHeight: 178, alignment: .center)
                .foregroundColor(.white)
            
            VStack {
                HStack {
                    Text("Title Three")
                        .bold()
                        .multilineTextAlignment(.leading)
                        .foregroundColor(.black)
                        .padding(.leading, 15)
                    
                    Spacer()
                    
                    Image(systemName: "info.circle.fill")
                        .scaledToFill()
                        .frame(alignment: .trailing)
                        .padding(.trailing, 15)
                    
                }
                .frame(maxWidth: 342, maxHeight: 50)
                .padding(EdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0))
                .background(Rectangle()
                    .foregroundColor(Color(red: 230/255, green: 234/255, blue: 242/255))
                    .opacity(0.5))
                
                Text("Language settings")
                Text("Subview test")
                
            }
        }
    }
}

And Custom NavBarViews

struct CustomNavBar: View {
    var body: some View {
        
        ZStack {
            Rectangle()
                .foregroundColor(.clear)
                .frame(width: .infinity, height: 70)
                .background(.mint)
            
            HStack {
                Button("Back") {
                }
                Spacer()
                Text("Heading")
                    .bold()
                    .foregroundColor(.white)
                Spacer()
                Button("Next") {
                }
            }
            .padding(.horizontal)
        }
        .navigationBarHidden(true)
    }
}

struct CustomNavBarContainerPreview<Content: View>: View {
    
    let content: Content
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    var body: some View {
        VStack(spacing: 0) {
            CustomNavBar()
            content
        }
    }
}

My GitHub test project here:
Ready to test

What’s the problem may be with this? How I can fix it?

I dug StackOverflow and didn’t find the answer. I saw this is a common bug in SwiftUI.
I tried to paste .ignoresSafeArea(.keyboard) and .ignoresSafeArea(.keyboard, edges: .bottom) everywhere in my code below (in ContentView, SettingsViews, custom Navigation Bar), to use Spacers() and .ignoresSafeArea(.all), and it didn’t give any results: View is still moving.
Also I used a hack with ScrollView to fix it, but it didn’t work correct for me.

May be I can embed UIKit code to control the View and the keyboard? But I don’t know how to do this.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to everyone who didn't pass by my problem, but unfortunately, I didn't find a suitable answer for me here. I figured it out myself, and the perfect solution for my case turned out to be placing my View in GeometryReader{} and applying the .ignoresSafeArea(.keyboard) modifier to it, and it worked!


  2. I know you wrote that adding a ScrollView didn’t help you. I copied your code one for one into a fresh Xcode project added a ScrollView around the VStack in ContentView and for me the keyboards don’t push the view up anymore after that.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search