Handling FocusStates on tvOS in a two layer approach

82 Views Asked by At

I'm currently building my first tvOS app in SwiftUI and I'm having trouble figuring out what exactly I'm doing wrong.

I was trying to build something similar to a two-level/layer UI. The first layer consists of the three sections in the ContentView. Those should be focusable when the app starts, if I select one of those three I want to move into the selected section. In my example here I added a list of buttons that should be focusable if I select the last section. I'm starting to lose my mind over this. Any help is highly appreciated.

import SwiftUI

struct ContentView: View {
  
  enum MainViewFocusSection {
    case sectionOne, sectionTwo, sectionThree, empty
  }
  
  @State var isListViewFocusable = false
  @State var isMainViewFocusable = true
  
  @FocusState var focus: MainViewFocusSection?
  @Namespace var streamFocusNamespace
  
  var body: some View {
    HStack {
      ZStack {
        Color.gray
      }
      .border(.red, width: focus == .sectionOne ? 5 : 0)
      .focusable(isMainViewFocusable)
      .focused($focus, equals: .sectionOne)
      ZStack {
        Color.orange
      }
      .border(.red, width: focus == .sectionTwo ? 5 : 0)
      .focusable(isMainViewFocusable)
      .focused($focus, equals: .sectionTwo)
      ZStack {
        Color.blue
        ListView(isFocusable: $isListViewFocusable)
      }
      .border(.red, width: focus == .sectionThree ? 5 : 0)
      .focusable(isMainViewFocusable)
      .focused($focus, equals: .sectionThree)
      .onTapGesture {
        isMainViewFocusable = false
        isListViewFocusable = true
        focus = nil
      }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

struct ListView: View {
  @Binding var isFocusable: Bool
  @FocusState private var focusedButtonIndex: Int?
  
  var body: some View {
    LazyVStack {
      ForEach(0..<10) { index in
        Button(action: {
          focusedButtonIndex = index
          print("\(index)")
        }) {
          Text("Button \(index)")
            .padding()
        }
        .buttonStyle(CardButtonStyle())
        .focused($focusedButtonIndex, equals: index)
        .id(index)
      }
    }
  }
}

struct ListView_Previews: PreviewProvider {
  static var previews: some View {
    ListView(isFocusable: .constant(true))
  }
}

0

There are 0 best solutions below