SwiftUI List 在任何视图更改时重置滚动
Posted
技术标签:
【中文标题】SwiftUI List 在任何视图更改时重置滚动【英文标题】:SwiftUI List reset scroll on any view change 【发布时间】:2021-04-20 07:47:04 【问题描述】:我有一个非常简单的列表,有一些部分,在同一视图中,我还有一个按钮在选择了列表项中的任何一个按钮时,它会使用状态变量控制,当发生这种情况时,如果列表是向下滚动,State 变量将更改(启用按钮)并且所有视图将刷新,导致我的列表滚动到顶部。我怎样才能避免这种滚动重置,我应该提到如果元素被删除或添加到列表中也会发生同样的情况,但是,我试图尽可能简化问题,这里是简化的代码 sn-p。
import SwiftUI
enum FavoritesListActiveSheet: Identifiable
case moveToSheet
var id: Int hashValue
struct Category: Identifiable
var id: UUID = UUID()
var name: String
extension Category
static var categories: [Category]
[
Category(name: "category 1"),
Category(name: "category 2")
]
struct FavoriteItem: Identifiable
var id: UUID = UUID()
var name: String
var category: String
var selected: Bool
extension FavoriteItem
static var favoriteItems: [FavoriteItem]
[
FavoriteItem(name: "Item 1", category: "category 1", selected: false),
FavoriteItem(name: "Item 2", category: "category 1", selected: false),
FavoriteItem(name: "Item 3", category: "category 1", selected: false),
FavoriteItem(name: "Item 4", category: "category 2", selected: false),
FavoriteItem(name: "Item 5", category: "category 2", selected: false),
FavoriteItem(name: "Item 6", category: "category 2", selected: false),
FavoriteItem(name: "Item 7", category: "category 2", selected: false),
FavoriteItem(name: "Item 8", category: "category 2", selected: false),
FavoriteItem(name: "Item 9", category: "category 2", selected: false),
FavoriteItem(name: "Item 10", category: "category 2", selected: false),
FavoriteItem(name: "Item 11", category: "category 2", selected: false),
FavoriteItem(name: "Item 12", category: "category 2", selected: false),
FavoriteItem(name: "Item 13", category: "category 2", selected: false),
FavoriteItem(name: "Item 14", category: "category 2", selected: false),
FavoriteItem(name: "Item 15", category: "category 2", selected: false),
FavoriteItem(name: "Item 16", category: "category 2", selected: false),
FavoriteItem(name: "Item 17", category: "category 2", selected: false),
FavoriteItem(name: "Item 18", category: "category 2", selected: false),
]
struct FavoritesRaw: View
@Binding var item: FavoriteItem
@State var refreshView: Bool = false
let onItemToggle: () -> ()
var body: some View
HStack
if (item.selected)
Image(systemName: "checkmark.circle")
else
Image(systemName: "circle")
Text (item.name)
.simultaneousGesture(TapGesture().onEnded
self.item.selected.toggle()
refreshView.toggle()
onItemToggle()
)
.contentShape(Rectangle())
class FavoritesViewModel: ObservableObject
var favorite_items: [FavoriteItem] = FavoriteItem.favoriteItems
struct FavoritesListView: View
@StateObject var viewModel: FavoritesViewModel = FavoritesViewModel()
@State var addtoButtonDisabled: Bool = true
@State var sheetDisplayed: FavoritesListActiveSheet?
var body: some View
NavigationView
VStack
List
ForEach (Category.categories) category in
Section (header: Text(category.name))
ForEach (self.viewModel.favorite_items.filter($0.category == category.name)) item in
FavoritesRaw(item: binding(for: item), onItemToggle:
addtoButtonDisabled = (self.viewModel.favorite_items.filter($0.selected == true).count == 0)
)
.textCase(nil)
.listStyle(PlainListStyle())
.id(UUID()) // no animation
.navigationBarTitle("Favorites", displayMode: .inline)
.toolbar
ToolbarItemGroup(placement: .navigationBarTrailing)
Button(action:
sheetDisplayed = .moveToSheet
)
Text("Add to...")
.disabled(addtoButtonDisabled)
.sheet(item: $sheetDisplayed) item in
// [Show a sheet then disable back the button]
.onAppear
addtoButtonDisabled = (self.viewModel.favorite_items.filter($0.selected == true).count == 0)
private func binding(for item: FavoriteItem) -> Binding<FavoriteItem>
guard let item_index = self.viewModel.favorite_items.firstIndex(where: $0.id == item.id ) else
fatalError("Can't find item in array")
return $viewModel.favorite_items[item_index]
【问题讨论】:
【参考方案1】:好像删除了
.id(UUID()) // 没有动画
正在解决我的问题。但是,我添加了这个来摆脱丑陋的动画,SwiftUI 提供了元素删除。
【讨论】:
以上是关于SwiftUI List 在任何视图更改时重置滚动的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:如何根据滚动视图的用户当前滚动位置同步/更改进度条进度?
SwiftUI - 防止列表在项目选择时将滚动位置重置为顶部
ScrollView 或 List,如何制作特定的可滚动视图 (SwiftUI)