我有一个显示从 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)
}
}
}
我该怎么办?谢谢你的帮助
当您有一个大列表(例如 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!
的操作。当这些值确实不存在并且您尝试访问它们时,它可能会导致崩溃。