如何解决SwiftUI 列表在任何视图更改时重置滚动
I have a very simple List with some Sections,in the same view I have also one button which will become enabled when any of list items are selected,this is controlled with a State variable,when this is happening,if list is向下滚动,状态变量将更改(以启用按钮)并且所有视图都将刷新,导致我的列表滚动到顶部。如何避免这种滚动重置,我应该提到如果元素被删除或添加到列表中也会发生同样的情况,但是,我试图尽可能地简化问题,这是简化的代码片段。
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",FavoriteItem(name: "Item 3",FavoriteItem(name: "Item 4",category: "category 2",FavoriteItem(name: "Item 5",FavoriteItem(name: "Item 6",FavoriteItem(name: "Item 7",FavoriteItem(name: "Item 8",FavoriteItem(name: "Item 9",FavoriteItem(name: "Item 10",FavoriteItem(name: "Item 11",FavoriteItem(name: "Item 12",FavoriteItem(name: "Item 13",FavoriteItem(name: "Item 14",FavoriteItem(name: "Item 15",FavoriteItem(name: "Item 16",FavoriteItem(name: "Item 17",FavoriteItem(name: "Item 18",]
}
}
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]
}
}
解决方法
好像删除
.id(UUID()) // 没有动画
正在解决我的问题。但是,我添加了这个以摆脱丑陋的动画,SwiftUI 提供了元素删除功能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。