Я хочу обновить отображаемый список до последнего состояния при возврате из пункта назначения перехода с помощью SwiftUI - PullRequest
1 голос
/ 16 марта 2020

ListView отображает список элементов, добавленных в избранное.

Go в DetailView и удаляет элемент из избранного.

И когда я возвращаюсь в представление списка, я хочу обновите его до последнего списка.

Как вы это делаете?

Код

ListView.swift

Отображается список типов карт 3х3.

struct ListView: View {
    @ObservedObject var fetcher = DataFetcher()
    private let columns: Int = 3

    var body: some View {
        GeometryReader { geometry in
            NavigationView {
                ScrollView() {
                    VStack {
                        ForEach(0..<self.fetcher.dataCount/self.columns) { rowIndex in
                            HStack {
                                ForEach(0..<self.columns) { columnIndex in
                                    self.getCell(
                                        item: self.getItem(rowIndex: rowIndex, columnIndex: columnIndex),
                                        width: self.cellWidth(width: geometry.size.width),
                                        height: self.cellHeight(width: geometry.size.width))
                                }
                            }
                        }

                      if (self.fetcher.dataCount % self.columns > 0) {
                          HStack {
                              ForEach(0..<self.fetcher.dataCount % self.columns) { lastColumnIndex in
                                  self.getCell(
                                      item: self.getItem(lastColumnIndex: lastColumnIndex),
                                      width: self.cellWidth(width: geometry.size.width),
                                      height: self.cellHeight(width: geometry.size.width))
                              }
                              Spacer()
                          }
                      }
                  }
                  .frame(maxWidth: .infinity)
                }
                .navigationBarTitle("list")
            }
        }
    }

    private func cellWidth(width: CGFloat) -> CGFloat {
        return (width  - 60) / CGFloat(columns)
    }

    private func cellHeight(width: CGFloat) -> CGFloat {
        return cellWidth(width: (width)) * 1.414
    }

    private func getItem(rowIndex: Int, columnIndex: Int) -> TrackModel {
        return fetcher.data[columns * rowIndex + columnIndex]
    }

    private func getItem(lastColumnIndex: Int) -> TrackModel {
        return self.fetcher.data[self.columns * (self.fetcher.dataCount / self.columns) + lastColumnIndex]
    }

    private func getCell(item: ItemModel, width: CGFloat, height: CGFloat) -> AnyView {
        return AnyView(
            NavigationLink(
                destination: etailView(itemModel: item)
            ) {
                ItemRow(itemModel: item)
                .frame(width: width, height: height)
            }
            .buttonStyle(PlainButtonStyle())
        )
    }
}

DataFetcher.swift

В Firestore есть коллекция «users» и «items».

Каждый документ пользователя имеет коллекцию "предметов".

"items" имеет ссылочный тип "item", а значение равно "items / documentID".

class DataFetcher: ObservableObject {
    typealias PublisherType = PassthroughSubject
    @Published var data: [TrackModel] = []
    @Published var dataCount: Int = 0
    private let userDefaults = UserDefaults.standard
    private let uid: String
    private var db: Firestore!
    private let dispatchGroup = DispatchGroup()
    private let dispatchQueue = DispatchQueue(label: "queue")

    init() {
        db = Firestore.firestore()
        uid = self.userDefaults.object(forKey: "userDataUid") as! String
        fetchData()
    }

    private func fetchData() {
        self.db.collection("users").document(uid).collection("items").getDocuments { (snaps, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            }

            guard let snaps = snaps else { return }

            for document in snaps.documents {
                self.dispatchGroup.enter()
                self.dispatchQueue.async(group: self.dispatchGroup) { [weak self] in
                    self?.asyncProcess(document: document) { (snap2: DocumentSnapshot) -> Void in
                        self!.data.append(TrackModel(
                            documentId: snap2.documentID,
                            title: snap2.data()!["title"] as! String,
                            image: snap2.data()!["image"] as! String
                        ))
                        self?.dispatchGroup.leave()
                    }
                }
            }

            self.dispatchGroup.notify(queue: .main) {
                self.dataCount = self.data.count
            }
        }
    }

    func asyncProcess(document: QueryDocumentSnapshot, completion: @escaping (_ snap: DocumentSnapshot) -> Void) {
        let refarence: DocumentReference = document.data()["item"] as! DocumentReference

        refarence.getDocument { (snap, err) in
            completion(snap!)
        }
    }
}

Postscript

Когда я перешел на экран подробностей с Модальный и вернувшийся на экран списка, я не смог получить.

что мне делать?

Button(action: {
    self.modalPresented.toggle()
}) {
    Text("Go to Detail")

}
.sheet(isPresented: self.$modalPresented) {
    DetailView(onDismiss: {
        self.modalPresented = false
        self.fetcher.fetchData()
    })
}

1 Ответ

1 голос
/ 18 марта 2020

Если вы имеете в виду повторную выборку, здесь возможен подход

  1. Сделайте вашу функцию выборки доступной для других
    class DataFetcher: ObservableObject {
        ...
        func fetchData() { // << here !
           ...

Инициировать повторное извлечение при исчезновении деталей

    NavigationLink(
        destination: DetailView(itemModel: item)
                         .onDisappear {
                             self.fetcher.fetchData() // << here !
                         }
    ) {
        ItemRow(itemModel: item)
        .frame(width: width, height: height)
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...