Any idea why Field 3
and Field 5
do not get visible when active if the previous field was using the normal keyboard?
In the following code, if you tap on Field 1
and immediately after you tap on Field 3
or Field 5
, they will not be visible; they get hidden by the keyboard.
Please note that Field 3
and Field 5
use the decimalPad
keyboard while the rest of the fields use the standard keyboard.
struct TextFieldScrollingIssue: View {
@State private var testInput:String = ""
var body: some View {
VStack{
Form {
TextField("Field 1", text:$testInput)
Spacer()
Spacer()
Spacer()
Spacer()
Spacer()
Spacer()
Spacer()
Section(header: Text("Section 1: ")) {
TextField("Field 2", text:$testInput)
TextField("Field 3", text:$testInput)
.keyboardType(.decimalPad)
}
Section(header: Text("Section 2: ")) {
TextField("Field 4", text:$testInput)
TextField("Field 5", text:$testInput)
.keyboardType(.decimalPad)
}
}
}
}
}
CodePudding user response:
I think the scrolling mechanism is confused because you used the same variable for all of the TextFields
. Obviously, in production, you would never have this scenario. The fix is simple, use different variables:
struct TextFieldScrollingIssue: View {
@FocusState var isFocused: String?
@State private var testInput:String = ""
@State private var decimalInput:String = ""
var body: some View {
VStack{
ScrollViewReader { scroll in
Form {
TextField("Field 1", text:$testInput)
.id("Field 1")
.focused($isFocused, equals: "Field 1")
Text(isFocused?.description ?? "nil")
Spacer()
Spacer()
Spacer()
Spacer()
Spacer()
Spacer()
Section(header: Text("Section 1: ")) {
TextField("Field 2", text:$testInput)
.id("Field 2")
.focused($isFocused, equals: "Field 2")
TextField("Field 3", text:$decimalInput)
.id("Field 3")
.focused($isFocused, equals: "Field 3")
.keyboardType(.decimalPad)
}
Section(header: Text("Section 2: ")) {
TextField("Field 4", text:$testInput)
.id("Field 4")
.focused($isFocused, equals: "Field 4")
TextField("Field 5", text:$decimalInput)
.id("Field 5")
.focused($isFocused, equals: "Field 5")
.keyboardType(.decimalPad)
}
}
.onChange(of: isFocused) { _ in
if let isFocused = isFocused {
DispatchQueue.main.async {
withAnimation {
scroll.scrollTo(isFocused)
}
}
}
}
}
}
}
}
Edit:
Based on the comment, I was able to reproduce. Edited code to use a ScrollviewReader
, @FocusState
and view ids to correct.