我想在使用SwiftUI从转换目的地返回时将显示的列表更新为最新状态



ListView显示添加到收藏夹的项目列表。

转到DetailView并从收藏夹中删除该项目。

当我返回到列表视图时,我想将其更新为最新的列表。

你是怎么做到的?

代码

ListView.swift

将显示3x3卡类型的列表。

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有一个"用户"one_answers"项目"的集合。

每个用户的文档都有一个"项目"集合。

"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!)
}
}
}

后记

当我使用Modal转到详细信息屏幕并返回列表屏幕时,我无法获取。

我该怎么办?

Button(action: {
self.modalPresented.toggle()
}) {
Text("Go to Detail")
}
.sheet(isPresented: self.$modalPresented) {
DetailView(onDismiss: {
self.modalPresented = false
self.fetcher.fetchData()
})
}

如果你的意思是重新获取,这里有一种可能的方法

  1. 让你的获取功能对其他人可用
class DataFetcher: ObservableObject {
...
func fetchData() { // << here !
...
  1. 当详细信息消失时启动重新提取

    NavigationLink(
    destination: DetailView(itemModel: item)
    .onDisappear {
    self.fetcher.fetchData() // << here !
    }
    ) {
    ItemRow(itemModel: item)
    .frame(width: width, height: height)
    }
    

最新更新