ScrollView in SwiftUI messes up keyboard navigation
While rebuilding some screens of my app with SwiftUI that existed before in UIKit, I have been facing a particular accessibility issue. It seems that using a `ScrollView` messes up the order of UI element navigation when using keyboard navigation (Full Keyboard Access). When embedding some `Text`, `TextField` and `Button` elements in that `ScrollView` the order of elements being focused when using Tab is completely off and some elements are not reachable at all. The same behavior does not reproduce when using Voice Over. When removing the surrounding `ScrollView` all works as expected. Here an example with which the issue is 100% reproducible:
struct ContentView: View {
@State var entry: String = ""
var body: some View {
ScrollView {
VStack {
VStack {
VStack {
Text("Text 1")
TextField(text: $entry, label: { Text("Text Field 1") })
}
Button(action: {}, label: {
Text("Button 1")
})
}
VStack {
VStack {
Text("Text 2")
TextField(text: $entry, label: { Text("Text Field 2") })
}
Button(action: {}, label: {
Text("Button 2")
})
}
}
}
}
}
#Preview {
ContentView()
}
The keyboard navigation order looks like this (by using Tab key):
Text Field 1 -> Text Field 2 -> Button 1
Button 2 is completely skipped.
The expected order is Text Field 1 -> Button 1 -> Text Field 2 -> Button 2
Simply remove the `ScrollView` in the example and it works as expected.
But I can't just remove the `ScrollView` because my page's content can become to large to fit on the whole screen (especially with larger accessibility font sizes).
I can reproduce this issue with:
- Xcode 15.4
- iOS 17.5.1 on iPhone 15 Pro
- iOS 16.7.8 on iPhone 8
- Swift 5