Yes, seems like since you wrap up HStack to ScrollView prefersDefaultFocus won't work correctly after that. I have a similar issue and can't get it to work for tvOS 14. Nevertheless, it works well with iOS 15 using @FocusState. So if you don't need tvOS 14 support you can use that approach. Here are my observations of the issue. What I try to achieve is set focus on the last item(10) if you press down on items 7 or 8. If I'm not wrapping up LazyVGrid into ScrollView everything works as expected. But as soon as I wrap up LazyVGrid into ScrollView when I press the down button on those items it always gets focused on the first item. Here is my code example and screenshot.
struct ContentView: View {
@Namespace var focusNamespace
@Environment(\.resetFocus) var resetFocus
@State private var defaultFocusIndex: Int = 0
@State var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 4)
var body: some View {
ScrollView() {
LazyVGrid(columns: columns) {
ForEach(items, id: \.self) { item in
Button {
} label: {
ItemView(title: item)
}
.prefersDefaultFocus(item == items[defaultFocusIndex], in: focusNamespace)
.onMoveCommand { moveCommandDirection in
guard let index = items.firstIndex(where: {$0 == item}) else {
return
}
if moveCommandDirection == .down, index >= items.count - columns.count {
defaultFocusIndex = items.count - 1
resetFocus(in: focusNamespace)
}
}
}
}
.focusScope(focusNamespace)
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: