gpt4 book ai didi

swiftui - 如何在 tvOS 上使用 SwiftUI 在多个水平列表之间导航

转载 作者:行者123 更新时间:2023-12-04 13:33:04 24 4
gpt4 key购买 nike

我在全局垂直列表中有多个可滚动的水平列表,并且难以管理焦点更改。
focus issue
我有两个主要问题:

  • 当一个 View 下面没有另一个 View 时,底部手势不会更新焦点。我希望焦点移到下方 View 附近。在我的 GIF 示例中,从第 1 节的第四个 View 到第 2 节的第二个 View 。
  • 当一个 View 的正下方没有另一个 View 时,底部手势会将焦点移动到垂直下方的 View 。我希望焦点移动到最近的底部 View 。在我的示例中,从第 1 节第三个 View 到第 2 节第二个 View ,而不是第 3 节第三个 View 。

  • 我的 tvOS 应用程序中有很多关于此问题的示例,我已使用 @Environment(\.resetFocus) var resetFocus 的组合修复了这些示例。和 prefersDefaultFocus viewModifier 但我在这个用例中挣扎。
    我还在 this question 上看到了另一个类似的用例但还没有答案。
    struct ContentView: View {
    var body: some View {
    VStack(alignment: .leading) {

    Text("Section 1")

    ScrollView(.horizontal) {
    HStack() {
    ForEach(0 ..< 10) { item in
    Button(action: {

    }) {
    FocusableRectangle()
    }.buttonStyle(CardButtonStyle())
    }
    }.padding(40)
    }

    Text("Section 2")

    ScrollView(.horizontal) {
    HStack() {
    ForEach(0 ..< 2) { item in
    Button(action: {

    }) {
    FocusableRectangle()
    }.buttonStyle(CardButtonStyle())
    }
    }.padding(40)
    }

    Text("Section 3")

    ScrollView(.horizontal) {
    HStack() {
    ForEach(0 ..< 3) { item in
    Button(action: {

    }) {
    FocusableRectangle()
    }.buttonStyle(CardButtonStyle())
    }
    }.padding(40)
    }

    Spacer()
    }
    }
    }

    struct FocusableRectangle: View {
    @Environment(\.isFocused) var isFocused: Bool
    @State var color = Color.blue

    var body: some View {
    Rectangle()
    .fill(color)
    .frame(width: 300.0, height: 200.0)
    .onChange(of: isFocused, perform: { value in
    color = value ? Color.red : Color.blue
    })
    }
    }

    最佳答案

    您需要将每个部分插入到容器中,例如 GroupZStack .然后,您可以尝试覆盖 .onMoveCommand.up.down方向以设置当前选择的部分。现在,您可以设置 .prefersDefaultFocus每个部分都有一个条件。您还需要拨打resetFocus选择变化时。

    struct ContentView: View {
    @Namespace var mainNamespace
    @Environment(\.resetFocus) var resetFocus

    @State private var selectedSection = SelectedSection.sec_1

    var body: some View {
    VStack(alignment: .leading) {

    Text("Section 1")

    Group(){
    ScrollView(.horizontal) {
    HStack() {
    ForEach(0 ..< 10) { item in
    Button(action: {

    }) {
    FocusableRectangle()
    }.buttonStyle(CardButtonStyle())
    }
    }.padding(40)
    }
    }.onMoveCommand(){direction in
    print(direction)
    if direction == .down{
    self.selectedSection = SelectedSection.sec_2
    }
    }.prefersDefaultFocus(self.selectedSection == SelectedSection.sec_1, in: mainNamespace)

    Text("Section 2")

    Group(){
    ScrollView(.horizontal) {
    HStack() {
    ForEach(0 ..< 2) { item in
    Button(action: {

    }) {
    FocusableRectangle()
    }.buttonStyle(CardButtonStyle())
    }
    }.padding(40)
    }
    }.onMoveCommand(){direction in
    print(direction)
    if direction == .down{
    self.selectedSection = SelectedSection.sec_3
    }
    if direction == .up{
    self.selectedSection = SelectedSection.sec_1
    }
    }.prefersDefaultFocus(self.selectedSection == SelectedSection.sec_2, in: mainNamespace)

    Text("Section 3")

    Group(){
    ScrollView(.horizontal) {
    HStack() {
    ForEach(0 ..< 3) { item in
    Button(action: {

    }) {
    FocusableRectangle()
    }.buttonStyle(CardButtonStyle())
    }
    }.padding(40)
    }
    }.onMoveCommand(){direction in
    print(direction)
    if direction == .up{
    self.selectedSection = SelectedSection.sec_2
    }
    }.prefersDefaultFocus(self.selectedSection == SelectedSection.sec_3, in: mainNamespace)

    Spacer()
    }
    .focusScope(mainNamespace)
    .onAppear(){
    print(selectedSection)
    }
    .onChange(of: self.selectedSection){newValue in
    resetFocus(in: mainNamespace)
    }
    }
    }

    关于swiftui - 如何在 tvOS 上使用 SwiftUI 在多个水平列表之间导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63828559/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com