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()
})
}