Fix tvOS focus navigation: add focusSection to all major UI sections

Focus couldn't move from DashboardView controls up to the
CategoryPillBar, or between sections within screens. Added
.platformFocusSection() to:

- ContentView: pill bar and content area as separate focus sections
- DashboardView: header, overview strip, hero+control section
- LeagueCenterView: schedule, standings, leaders, teams sections

This lets the tvOS Focus Engine navigate vertically between all
sections with d-pad up/down.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-12 17:05:17 -05:00
parent f59df9b04d
commit 7568a3b9d3
3 changed files with 9 additions and 1 deletions

View File

@@ -22,6 +22,7 @@ struct ContentView: View {
) )
.padding(.horizontal, DS.Spacing.edgeInset) .padding(.horizontal, DS.Spacing.edgeInset)
.padding(.top, navPadTop) .padding(.top, navPadTop)
.platformFocusSection()
if showsTicker { if showsTicker {
ScoresTickerView() ScoresTickerView()
@@ -43,6 +44,7 @@ struct ContentView: View {
} }
} }
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.platformFocusSection()
} }
} }
.task { .task {

View File

@@ -120,6 +120,7 @@ struct DashboardView: View {
ScrollView { ScrollView {
VStack(alignment: .leading, spacing: contentSpacing) { VStack(alignment: .leading, spacing: contentSpacing) {
headerSection headerSection
.platformFocusSection()
if viewModel.isLoading { if viewModel.isLoading {
loadingState loadingState
@@ -127,7 +128,9 @@ struct DashboardView: View {
errorState(error) errorState(error)
} else { } else {
overviewStrip overviewStrip
.platformFocusSection()
heroAndControlSection heroAndControlSection
.platformFocusSection()
if !viewModel.liveGames.isEmpty { if !viewModel.liveGames.isEmpty {
gameShelf( gameShelf(

View File

@@ -35,16 +35,18 @@ struct LeagueCenterView: View {
} }
scheduleSection scheduleSection
.platformFocusSection()
#if os(tvOS) #if os(tvOS)
// Side-by-side: standings left, leaders right
HStack(alignment: .top, spacing: 24) { HStack(alignment: .top, spacing: 24) {
standingsSection standingsSection
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.platformFocusSection()
if !viewModel.leagueLeaders.isEmpty { if !viewModel.leagueLeaders.isEmpty {
leadersColumnSection leadersColumnSection
.frame(width: 420) .frame(width: 420)
.platformFocusSection()
} }
} }
#else #else
@@ -56,6 +58,7 @@ struct LeagueCenterView: View {
#endif #endif
teamsSection teamsSection
.platformFocusSection()
if let selectedTeam = viewModel.selectedTeam { if let selectedTeam = viewModel.selectedTeam {
teamProfileSection(team: selectedTeam) teamProfileSection(team: selectedTeam)