SwiftUI changing keyboard type resets scroll on Form

I am seeing an issue in my SwiftUI app where when I have a Form with multiple TextField types that use different keyboards it causes the scrolling to reset when taping on a new textfield that changes the keyboard.

In my sample code below if you do the following:

Tap "Field 1" -> Scroll down -> tap "Field 3" or "Field 5"

It will change the open keyboard to the numberPad/decimalPad keyboard and reset the views scrolling to the top resulting in your focused field to be behind the keyboard.

If you do the following instead:

Tap "Field 1" -> Scroll down -> tap "Field 2" or "Field 4"

It will focus on the new textfield and NOT reset the view scrolling, working as intended.

This issue seems to only affect the number keyboards as if you notice in my sample "Field 4" has the emailAddress keyboard and it doesn't cause the scroll reset. It also doesn't seem to happen when you move focus from a number field to a standard keyboard text field or tap a number field as your first focus.

Has anyone else seen this issue or have any ideas on fixes/workarounds for this?

import SwiftUI

struct ContentView: View {
    @State private var stringOne: String = ""
    @State private var stringTwo: String = ""
    @State private var stringThree: String = ""
    @State private var numberOne: Int = 1
    @State private var decimalOne: Double = 0.0
    
    var body: some View {
        Form {
            Section("Section 1:") {
                TextField("Field 1", text: $stringOne)
                Spacer()
                Spacer()
                Spacer()
                Spacer()
                Spacer()
                Spacer()
                Spacer()
                Spacer()
            }
            
            Section("Section 2:") {
                TextField("Field 2", text: $stringTwo)
                TextField("Field 3", value: $numberOne, format: .number)
                    .keyboardType(.numberPad)
            }
            
            Section("Section 3:") {
                TextField("Field 4", text: $stringThree)
                    .keyboardType(.emailAddress)
                TextField("Field 5", value: $decimalOne, format: .number)
                    .keyboardType(.decimalPad)
            }
        }
    }
}

#Preview {
    ContentView()
}

Unfortunately, I have exactly the same problem 😬

You could work with a format style but the input is only validated after pressing Return. Since the keyboard would not be .numberPad, all characters could be entered. In addition, you would need to have a default input, which would probably be 0. Both look ugly in the form.

You could probably have a workaround with the UITextField, but I personally don't like to mix SwiftUI and UIKit or only if there is no other way.

SwiftUI changing keyboard type resets scroll on Form
 
 
Q