У меня есть @Environment, в котором хранятся все общие данные для моих просмотров. Одно из моих представлений использует одну из своих переменных для представления списка сворачиваемых элементов. Чтобы сделать список сворачиваемым, я использую @State независимо от того, истинно оно или ложно, чтобы развернуть сворачиваемое содержимое, внутри этого списка я хочу, чтобы пользователь мог удалить его элементы, поэтому я сделал функцию, которая удаляет элемент из переменной в @Environment и обновляет представление . Проблема в том, что состояние меняется на значение по умолчанию, а расширенный список свертывается. Я хотел бы знать, как сохранить предыдущие состояния или, может быть, сказать мои взгляды, которые повторно отображают только те части, которые действительно меняются.
Это мой объект Environment. Все мои взгляды имеют к этому доступ.
class GlobalData:ObservableObject {
@Published var SpoonData: [Item?] = []
@Published var currentTab: Int = 0
func deleteSpoonData(at offsets: IndexSet) {
self.SpoonData.remove(atOffsets: offsets)
}
func addSpoonData(item: Item, itemList: Items){
let exists = SpoonData.firstIndex(where: {$0?.ItemId == item.ItemId})
var rt = item
rt.ItemList = itemList
if exists == nil {
self.SpoonData.append(rt)
}
}
func deleteProductFromItemList(product: Product, itemId: Int) {
let fatherIndex = self.SpoonData.firstIndex { item -> Bool in
item?.ItemId == itemId
}
let childIndex = (self.SpoonData[fatherIndex!]?.ItemList?.ItemList?.firstIndex(where: { productfiltered -> Bool in
productfiltered?.EntryID == product.EntryID
}))!
print(self.SpoonData[fatherIndex!]?.ItemList?.ItemList![childIndex])
self.SpoonData[fatherIndex!]?.ItemList?.ItemList!.remove(at: childIndex)
}
}
Это представление, представляющее список.
struct SpoonListItemView: View {
private let viewModel: SpoonListItemViewModel
@State private var isCollapsed: Bool = false
init(viewModel: SpoonListItemViewModel) {
self.viewModel = viewModel
}
var body: some View {
VStack {
VStack {
HStack(alignment: .top) {
if self.viewModel.ItemType == 1 {
AsyncImage(url: viewModel.ItemImageUrl, size: CGSize(width: 45.0, height: 45.0), contentMode: .fit)
.clipShape(Rectangle())
} else {
AsyncImage(url: viewModel.ItemImageUrl, size: CGSize(width: 45.0, height: 45.0), contentMode: .fit)
.clipShape(Circle())
}
VStack(alignment: .leading) {
Text("\(viewModel.ItemName)")
.font(.custom("NunitoSans-Bold", size: 14))
.lineLimit(1)
.multilineTextAlignment(.leading)
Text(viewModel.ItemType == 1 ? "Receta" : "Producto")
.foregroundColor(Color("textColor"))
.font(.custom("NunitoSans-Light", size: 12))
}
Spacer()
}.frame(height: 50)
.padding(EdgeInsets(top: 0, leading: 24, bottom: 0, trailing: 24)).onTapGesture {
self.isCollapsed.toggle()
}
}
if self.viewModel.ItemType == 1 {
if self.isCollapsed {
SpoonListProductView(viewModel: SpoonListProductViewModel(items: self.viewModel.ItemList, father: self.viewModel.ItemId))
}
}
}
}
}
And this is the view that present the childs when is expanded
struct SpoonListProductView: View {
@EnvironmentObject var globalData: GlobalData
@ObservedObject var viewModel: SpoonListProductViewModel
@State private var isInEditingMode: Bool = false
var fatherId: Int?
init(viewModel: SpoonListProductViewModel) {
self.viewModel = viewModel
}
var body: some View {
VStack(alignment: .leading) {
ForEach(viewModel.dataSource) { vm in
Group{
HStack {
SpoonProductView.init(viewModel: vm).onLongPressGesture {
self.isInEditingMode = true
}
Spacer()
if self.isInEditingMode {
Image(systemName: "trash.fill").foregroundColor(Color("textColor")).onTapGesture {
self.delete(vm: vm)
}
}
}
Divider()
}
}
}.padding(EdgeInsets(top: 8, leading: 8, bottom: 0, trailing: 8))
}
func delete(vm: ProductViewModel) {
//self.viewModel.ItemList?.remove(atOffsets: offsets)
self.globalData.deleteProductFromItemList(product: vm.product, itemId: self.viewModel.father!)
}
}
Это код для списка:
struct SpoonListView: View {
@EnvironmentObject var globalData: GlobalData
@ObservedObject var viewModel: SpoonListViewModel
var items: [Item?]
init(items: [Item?] ) {
self.items = items
self.viewModel = SpoonListViewModel(items: self.items)
}
var body: some View {
SpoonListItemsView(viewModel: viewModel.dataSource!)
}
}
И это его viewModel:
class SpoonListViewModel: ObservableObject, Identifiable {
@Published var dataSource: SpoonListItemsViewModel? = nil
var items: [Item?]
init(items: [Item?]) {
self.items = items
self.dataSource = SpoonListItemsViewModel(items: self.items as! [Item])
}
}