使用 SwiftUI 从转换目的地返回时,我想将显示的列表更新为最新状态
Posted
技术标签:
【中文标题】使用 SwiftUI 从转换目的地返回时,我想将显示的列表更新为最新状态【英文标题】:I want to update the displayed list to the latest state when returning from the transition destination with SwiftUI 【发布时间】:2020-06-27 16:05:23 【问题描述】: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 具有“用户”和“项目”的集合。
每个用户的文档都有一个“项目”的集合。
“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 !
...
当细节消失时启动重新获取
NavigationLink(
destination: DetailView(itemModel: item)
.onDisappear
self.fetcher.fetchData() // << here !
)
ItemRow(itemModel: item)
.frame(width: width, height: height)
【讨论】:
以上是关于使用 SwiftUI 从转换目的地返回时,我想将显示的列表更新为最新状态的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中从一个详情页跳转到另一个详情页并返回列表页?