У меня есть @Environment, в котором хранятся все данные общего доступа для моих просмотров. Одно из моих представлений использует одну из своих переменных, чтобы представить список со сворачиваемыми элементами. Чтобы сделать список свертываемым, я использую @State, имеет ли значение true или false, чтобы развернуть свертываемое содержимое, внутри этого списка я хочу, чтобы пользователь мог удалить его элементы, поэтому я создал функцию, которая удаляет элемент из переменной в @Environment и обновляет представление , Проблема состоит в том, что State меняет свое значение по умолчанию, и расширенный список может быть свернут. Я хотел бы знать, как сохранить прежние состояния или, может быть, сказать, что мои взгляды изменяют только те части, которые действительно меняются.
Это мой объект окружающей среды. Все мои представления имеют доступ к этому.
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])
}
}