tvOS:如何将焦点集中到列表的下一个 50 个元素?

问题描述 投票:0回答:1

我有一个显示从 1 到 1000 的所有整数的列表。当用户点击遥控器上的 > 按钮时,我想在该列表中前进 50 个项目。这是我尝试过的,但是当我按 > 按钮时,我得到的信息是 focus 不为零,但它没有更新。

struct ContentView: View {
    @FocusState private var focused: Int?
    
    var body: some View {
        List(1..<1001) { i in
            Button(action: {}) {
                Text("\(i)")
            }
            .focused($focused, equals: i)
        }
        .onMoveCommand { direction in
            switch direction {
            case .right:
                if focused == nil {
                    print("focused is nil")
                } else {
                    print("focused is not nil")
                    focused! += 50
                }
            default:
                break
            }
        }
        .onChange(of: focused) { oldValue, newValue in
            print(newValue)
        }
    }
}

我该怎么办?谢谢你的帮助

swiftui tvos
1个回答
0
投票

当您有一个大列表(例如 1000 个数字)时,它不会立即加载所有内容 - 它只是显示需要的内容。这就是 SwiftUI 中 List 的延迟加载本质。

您可以使用

ScrollViewReader
并使用其代理来帮助您在列表中跳转,甚至跳转到尚未显示的部分:

struct ContentView: View {
    @FocusState private var focused: Int?

    var body: some View {
        ScrollViewReader { proxy in
            List(1..<1000, id: \.self) { i in
                Button(action: {}) {
                    Text("\(i)")
                }
                .focused($focused, equals: i)
                .id(i)
            }
            .onMoveCommand(perform: handleMoveCommand(proxy: proxy))
        }
    }

    private func handleMoveCommand(proxy: ScrollViewProxy) -> (MoveCommandDirection) -> Void {
        return { direction in
            if direction == .right {
                withAnimation {
                    proxy.scrollTo(50)
                    focused = 50
                }
            }
        }
    }
}

当您按下右键时,列表会平滑滚动到编号 50,即使它之前不在屏幕上。为此,请使用

proxy.scrollTo(50)
。通过
focused = 50
,列表知道数字 50 是当前操作的位置。

尽量避免在代码中执行类似

focused!
的操作。当这些值确实不存在并且您尝试访问它们时,它可能会导致崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.