Nano Hash - криптовалюты, майнинг, программирование

При обновлении среды представление повторно отображается со всеми его состояниями Swiftui

У меня есть @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])
    }
}
04.02.2020

Ответы:


1

Проблема здесь не в SpoonListItemView, а в ведьме взгляда. @State должен сохраняться между рендерами, но в этом случае у вас есть List или ForEach элементов в вашем (допустим) SpoonListView. который повторно отображает список при каждом изменении. Я думаю, что одним из решений может быть перемещение состояния openIndex в список или на более высокий уровень.

Кроме того, вы можете замаскировать событие в GlobalData, переопределив синтезируемое с помощью let objectWillChange = ObservableObjectPublisher(), но это будет означать, что вам придется вызывать в других случаях вручную. Так что я бы этого избежал.

PS: Для лучшего понимания не могли бы вы также добавить код списка?

04.02.2020
  • Спасибо за Ваш ответ. Я уже обновил свой вопрос и добавил код для списка. 05.02.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..