【发布时间】:2021-05-15 16:05:39
【问题描述】:
简短:我视图中的图像在第一次加载后没有更新。该 URL 与之前加载的视图保持一致,但未从存储中获取 URL 或数据的视图的其余部分将被更新。
完整:我有两个视图,一个ListView 和一个DetailView。
在ListView 中,我显示List 类型的列表。详细视图应该显示来自List.profiles 的每个Profile。为此,我将每个字符串 uid 存储在 List.profiles 中并调用 model.fetchProfiles 以获取每个选定列表的配置文件。
在第一个选中的List model.fetchProfiles 返回文档,model.profiles 在DetailView 中显示数据。
当第一次加载DetailView 时,出现的ProfileRow 会被调用并记录获取的配置文件。然后ProfileRow 从imagePath 加载imageURL 并使用它来获取图像。
控制台:加载列表1
卡片出现了:个人资料 []
卡出现:SortedProfiles [] 卡片行
出现卡片行:个人资料profiles/XXXXXX/Profile/profile.png
出现卡片行:SortedProfiles profiles/XXXXXX/Profile/profile.png
从图片路径获取url:profiles/XXXXXX/Profile/profile.png
图片网址:https://firebasestorage.googleapis.com/APPNAME/profiles%XXXXXXX
当从ListView 中选择第二个List 时,ProfileRow didAppear 没有被调用;
if model.profiles.count > 0 {
print("CARD ROW DID APPEAR: Profiles \(model.profiles[0]. imgPath)")
print("CARD ROW DID APPEAR: Sorted \(model.sortedProfiles[0].imgPath)")
}
并且在ListView 中选择List 时不会再出现,但是ProfileRow 中的其余配置文件数据会显示,例如名称,因此必须获取数据。
ImagePath 与加载完全相同图像的第一个视图相同。 Profile 的所有其他属性(例如名称)均已正确加载。
控制台:加载 List2
卡片出现了:个人资料 []
卡出现:SortedProfiles [] 卡片行
从图片路径获取url:profiles/XXXXXX/Profile/profile.png 图片网址: https://firebasestorage.googleapis.com/APPNAME/profiles%XXXXXXX
如果我然后导航到List1,则出现List2 的图像,如果我重新选择List2,图像看起来很好。 The image show is correct on first load, and when selecting another list it always the one from before.
谁能帮帮我?
第一次查看
struct ListViw: View {
@EnvironmentObject var model: Model
var body: some View {
VStack {
ForEach(model.lists.indices, id: \.self) { index in
NavigationLink(
destination: DetailView()
.environmentObject(model)
.onAppear() {
model.fetchProfiles()
}
) {
ListRow(home:model.lists[index])
.environmentObject(model)
}
.isDetailLink(false)
}
}
}
}
详细视图卡片
struct ProfilesCard: View {
@EnvironmentObject var model: Model
var body: some View {
VStack(alignment: .trailing, spacing: 16) {
if !model.sortedProfiles.isEmpty {
VStack(alignment: .leading, spacing: 16) {
ForEach(model.sortedProfiles.indices, id: \.self) { index in
ProfileRow(
name: "\(model.sortedProfiles[index].firstName) \(model.sortedProfiles[index].lastName)",
imgPath: model.sortedProfiles[index].imgPath,
index: index)
.environmentObject(model)
}
}
.padding(.top, 16)
}
}//End of Card
.modifier(Card())
.onAppear() {
print("CARD DID APPEAR: Profiles \(model.profiles)")
print("CARD DID APPEAR: SORTED \(model.sortedTenants)")
}
}
}
struct ProfileRow: View {
@EnvironmentObject var model: Model
@State var imageURL = URL(string: "")
var name: String
var imgPath: String
var index: Int
private func loadImage() {
print("load image: \(imgPath)")
DispatchQueue.main.async {
fm.getURLFromFirestore(path: imgPath, success: { (imgURL) in
print("Image URL: \(imgURL)")
imageURL = imgURL
}) { (error) in
print(error)
}
}
}
var body: some View {
VStack(alignment: .leading, spacing: 12) {
HStack(alignment: .center, spacing: 12) {
KFImage(imageURL,options: [.transition(.fade(0.2)), .forceRefresh])
.placeholder {
Rectangle().foregroundColor(.gray)
}
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 32, height: 32)
.cornerRadius(16)
// Profile text is always displayed correctly
Text(name)
.modifier(BodyText())
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.onAppear() {
print("CARD ROW")
// Crashes if check is not there
if model.profiles.count > 0 {
print("CARD ROW DID APPEAR: Profiles \(model.profiles[0]. imgPath)")
print("CARD ROW DID APPEAR: Sorted \(model.sortedProfiles[0].imgPath)")
}
loadImage()
}
}
}
型号
class Model: ObservableObject {
init() {
fetchData()
}
@Published var profiles: [Profile] = []
var sortedProfiles: [Profile] {return profiles.removeDuplicates }
@Published var list: List? {
didSet {
fetchProfiles()
}
}
func fetchData() {
if let currentUser = Auth.auth().currentUser {
email = currentUser.email!
db.collection("lists")
.whereField("createdBy", isEqualTo: currentUser.uid)
.addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
return
}
self.lists = documents.compactMap { queryDocumentSnapshot -> List? in
return try? queryDocumentSnapshot.data(as: List.self)
}
}
}
}
func fetchProfiles() {
profiles.removeAll()
for p in list!.profiles {
firestoreManager.fetchProfile(uid: t, completion: { [self] profile in
profiles.append(profile)
})
}
}
}
更新
到目前为止,我尝试将didSet 用于ImgPath 或ImgURL,但仍然没有运气。也试过直接使用model.profiles。
【问题讨论】:
标签: firebase google-cloud-firestore swiftui combine