【发布时间】:2021-11-28 21:13:42
【问题描述】:
我有一个具有 3 列视图的 macOS 应用程序。在第一列中,有一个List 很长的项目——可能有几百个项目。
如果我的每个项目的 NavigationLink 包含一个 isActive 参数,则在单击 NavigationLinks 时,我会在列表中出现不可预测/不需要的滚动行为。
例如,如果我向下滚动到第 100 项并单击它,List可能决定向上滚动到第 35 项左右(活动的NavigationLink 不在框架)。这种行为似乎有点不确定——它并不总是滚动到同一个地方。如果我在列表中滚动到我想要的项目,然后等待系统滚动条消失后再点击 NavigationLink,似乎不太可能滚动到一个奇怪的位置,但它没有让问题彻底消失。
如果我删除isActive 参数,则在单击NavigationLinks 时会保持滚动位置。
struct ContentView : View {
var body: some View {
NavigationView {
SidebarList()
Text("No selection")
Text("No selection")
.frame(minWidth: 300)
}
}
}
struct Item : Identifiable, Hashable {
let id = UUID()
var name : String
}
struct SidebarList : View {
@State private var items = Array(0...300).map { Item(name: "Item \($0)") }
@State private var activeItem : Item?
func navigationBindingForItem(item: Item) -> Binding<Bool> {
.init {
activeItem == item
} set: { newValue in
if newValue { activeItem = item }
}
}
var body: some View {
List(items) { item in
NavigationLink(destination: InnerSidebar(),
isActive: navigationBindingForItem(item: item) //<-- Remove this line and everything works as expected
) {
Text(item.name)
}
}.listStyle(SidebarListStyle())
}
}
struct InnerSidebar : View {
@State private var items = Array(0...100).map { Item(name: "Inner item \($0)") }
var body: some View {
List(items) { item in
NavigationLink(destination: Text("Detail")) {
Text(item.name)
}
}
}
}
我想保留isActive,因为我有一些程序导航,我希望能够做到这一点取决于它。例如:
Button("Go to item 10") {
activeItem = items[10]
}
有什么方法可以在NavigationLink 上使用isActive 并避免不可预知的滚动行为?
(使用 macOS 11.3 和 Xcode 13.0 构建和测试)
【问题讨论】: