我在SwiftUI中遇到问题,我的downloadURL图像未发布到可见项的视图中。当我滚动时,不在视图中的SwiftUI元素会得到更新。问题在于,最初呈现视图时,图像URL为“”(空白)。因此,将按预期呈现默认图像。虽然,当downloadURL任务完成时,图像不会更新。如果我在属性上使用willSet和/或objectWillChange.send()的组合,则会更新1张图片,但只会更新1张。
高流量:
这是查看代码
import SwiftUI
import struct Kingfisher.KFImage
import Firebase
struct SeriesView: View {
// Firebase auth
@EnvironmentObject var authState: AuthenticationState
// Listen for view model state changes, i.e. series
@ObservedObject var seriesList = SeriesList()
private func signoutTapped() {
authState.signout()
}
// search bar
@State var searchText = ""
@State var isSearching = false
// firebase
//@State private var imageURL = URL(string: "")
@State private var imageURLString = ""
let storage = Storage.storage()
// view boday
var body: some View {
NavigationView {
ScrollView {
SearchBar(searchText: $searchText, isSearching: $isSearching)
LazyVGrid(columns: [
GridItem(.flexible(minimum: 100, maximum: 200), spacing: 16, alignment: .top),
GridItem(.flexible(minimum: 100, maximum: 200), spacing: 16, alignment: .top),
GridItem(.flexible(minimum: 100, maximum: 200), spacing: 16)
], alignment: .leading, spacing: 16, content: {
// filter for search entry
ForEach(seriesList.seriesArray//) { series in
.filter({"\($0.uniqueId)".contains(searchText)
|| "\($0.recordName)".contains(searchText)
|| "\($0.seriesName)".contains(searchText)
|| "\($0.fromYear)".contains(searchText)
|| "\($0.toYear)".contains(searchText)
|| searchText.isEmpty}), id: \.self) { series in
SeriesInfo(series: series)
}
}).padding(.horizontal, 12)
}
.navigationBarTitle(kMyToyBoxText)
.navigationBarItems(trailing: Button(action: signoutTapped, label: {
Image(systemName: "person.circle")
Text("Logout")
}))
}
}
}
struct SeriesInfo: View {
let series: Series
var body: some View {
NavigationLink(
destination: DetailView(series: series.seriesName)) {
VStack(alignment: .leading, spacing: 4) {
KFImage(URL(string: series.imageFirebaseURLString))
.onSuccess { r in
}
.onFailure { error in
}
.placeholder {
// Placeholder while downloading.
kMyToyBoxLogoImage
.resizable()
.font(.largeTitle)
.opacity(0.3)
.scaledToFit()
.cornerRadius(22)
}
.cancelOnDisappear(true) // cancel if scrolled past
.resizable()
.scaledToFit()
.cornerRadius(22)
Text(series.seriesName)
.font(.system(size: 10, weight: .semibold))
.padding(.top, 4)
// convert to strings to avoid commas
Text("\(String(series.fromYear)) - \(String(series.toYear))")
.font(.system(size: 9, weight: .regular))
Spacer()
}
}
}
}
我的Series类(也尝试作为结构,但是它改变了行为)
// series class
class Series: Identifiable, ObservableObject {
var id = UUID()
let uniqueId: String
let recordName: String
let seriesName: String
let fromYear: Int
let toYear: Int
let isMyToyBoxActive: Bool
let logoImageName: String
// generated data and needs to be published
@Published var imageFirebaseURLString: String
init (uniqueId: String, recordName: String, seriesName: String, fromYear: Int, toYear: Int, isMyToyBoxActive: Bool, logoImageName: String, imageFirebaseURLString: String = "") {
self.uniqueId = uniqueId
self.recordName = recordName
self.seriesName = seriesName
self.fromYear = fromYear
self.toYear = toYear
self.isMyToyBoxActive = isMyToyBoxActive
self.logoImageName = logoImageName
self.imageFirebaseURLString = imageFirebaseURLString
}
}
extension Series: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self).hashValue)
}
}
extension Series: Equatable {
public static func ==(lhs: Series, rhs: Series) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
}
ModelView代码-此代码将按预期的功能填充视图,但不包括downloadURL调用中的照片数据
// Series listener and data retriever
class SeriesList: ObservableObject {
@Published var seriesArray = [Series]()
init() {
//... code removed for getting Series file data from Firebase
let series: Series = self.getSeriesFromString(stringSeries: $0)
self.seriesArray.append(series)
// set the image
let storageRefImage = storage.reference().child(kSeriesImageRoot)
let seriesImageRef = storageRefImage.child(series.logoImageName)
// local image
seriesImageRef.downloadURL { url, error in
if let error = error {
}
else
{
series.imageFirebaseURLString = url!.absoluteString // <-- code to update the image URL
}
}
}
}
答案 0 :(得分:1)
在信息视图中也进行观察
struct SeriesInfo: View {
@ObservedObject var series: Series // << here !!