Found a way to achieve it. defaultFocus modifier allows you to say which element should have the default focus. Plus, we track which was the last focused (aka remembersLastFocusedIndexPath from UIKit)
@main
struct FocusApp: App {
var body: some Scene {
WindowGroup {
VStack(spacing: 50) {
CustomRow()
CustomRow()
}
}
}
}
struct CustomRow: View {
let items = [1, 2, 3, 4]
@FocusState private var currentFocusItem: Int?
@State private var lastFocusItem: Int?
var body: some View {
ScrollView(.horizontal) {
LazyHStack(spacing: 50) {
ForEach(items, id: \.self) { item in
Button { } label: {
Text("Item \(item)")
.frame(width: 300, height: 300, alignment: .center)
.background(Color.red)
}
.focused($currentFocusItem, equals: item)
}
}
}
.defaultFocus($currentFocusItem, lastFocusItem ?? items.first, priority: .userInitiated)
.onChange(of: currentFocusItem) {
if currentFocusItem != nil {
lastFocusItem = currentFocusItem
}
}
}
}