2

I have a Scrollview with just textfields in it. I want to be able to tap on any textfield and have the keyboard push it up slightly.

struct DetailView: View {
    @EnvironmentObject var vm: ViewModel

    var body: some View {
        ScrollView {
            VStack {
                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                TextField("Enter stuff", text: $vm.username)
                    .padding(.bottom, 20)

                Group {
                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)

                    TextField("Enter stuff", text: $vm.username)
                        .padding(.bottom, 20)
                }
            }
        }
    }
}

This works perfectly when there's no padding/styling in the textfield. If I use a custom textfield with styling (borders, padding), the keyboard hovers over part of the textfield. This is my custom textfield:

struct NotesField: View {
    @Binding var value: String

    init(_ value: Binding<String>) {
        self._value = value
    }

    var body: some View {
        TextField("Enter stuff", text: $value)
        .padding()
        .overlay(
            RoundedRectangle(cornerRadius: 10)
                .stroke(Color.gray, lineWidth: 1)
        )
    }
}

It's well known that ios14 handles this for you automatically so I want a solution where I don't have to use a view modifier to listen to when the keyboard is opened or not.

2
  • 1
    Do you find any solutions? Commented Apr 26, 2022 at 15:43
  • I also facing this issue. The accepted answer is not working for textfields with custom border and padding Commented Jun 5 at 6:24

1 Answer 1

1

If you are using iOS 14+ with scrollview or have the option to use scrollview.

https://developer.apple.com/documentation/swiftui/scrollviewproxy https://developer.apple.com/documentation/swiftui/scrollviewreader

Below might help

    ScrollViewReader { (proxy: ScrollViewProxy) in
        ScrollView {
            view1().frame(height: 200)
            view2().frame(height: 200)

            view3() <-----this has textfields 
                .onTapGesture {
                    proxy.scrollTo(1, anchor: .center)
                }
                .id(1)

            view4() <-----this has text editor
                .onTapGesture {
                    proxy.scrollTo(2, anchor: .center)
                }
                .id(2)

            view5().frame(height: 200)
            view6().frame(height: 200)
            submtButton().frame(height: 200)
        }
    }

imp part from above is

     anyView().onTapGesture {
          proxy.scrollTo(_ID, anchor: .center)
     }.id(_ID)

Hope this helps someone :)

Sign up to request clarification or add additional context in comments.

1 Comment

This works perfectly if you use the default textfield but I realized that when you have a custom textfield or textfield with border and padding, it lies on top of the textfield exactly and doesn't push the whole view up

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.