【问题标题】:How do I load multiple images in SwiftUI?swiftui同时加载多张图片
【发布时间】:2021-06-14 22:15:53
【问题描述】:

目前我有一个从 url 加载图像的图像加载器。但是所有的图像都是一样的。有谁知道我做错了什么?

@State var outfitimage: UIImage?

// .... a lot of lines in between ..... 


        LazyVGrid(columns: columns, spacing: 20) {
            ForEach(data, id: \.id) { item in
                VStack {
                    Text(item.displayname.capitalized)
                        .font(.title3)
                    Image(uiImage: outfitimage!)
                        .resizable()
                        .cornerRadius(15)
                }
                .onAppear{
                    downloadimage(imagename: item.user)
                }

            }
        }


// .... a lot of lines in between ....

func downloadimage(imagename: String) {
    let userimage = "outfits/" + (imagename) + ".jpg"

    Storage.storage().reference().child(userimage).getData(maxSize: 1048576) {
        (imageDataMyOutfit, Error) in
        if let Error = Error {
            print("an error accured: " + Error.localizedDescription)
        } else {
            if let imageDataMyOutfit = imageDataMyOutfit {
                self.outfitimage = UIImage(data: imageDataMyOutfit)
            } else {
                print("couldn't unwrap image data")
            }
        }
    }
}

它使用存储所有图像的 Firebase 存储。我真的不知道我做错了什么。

【问题讨论】:

    标签: image swiftui load


    【解决方案1】:

    您只有一个带有UIImage 的@State 变量,因此每次从您的downloadimage 函数加载新图像时,它都会覆盖该值。

    您可以通过以下几种方式解决此问题:

    1. 使用imagename 的键(您当前传递到download imageUIImage 的值)创建一个字典。然后,从该字典中动态提取。我也考虑移动所有这些变成ObservableObject

    2. 使用@State 变量将每个 Image 封装在其自己的子视图中,以保持其加载状态。

    第一个版本可能如下所示:

    class ImagesLoader : ObservableObject {
        @Published var images : [String:UIImage] = [:]
        
        func downloadImage(imagename: String) {
            let userimage = "outfits/" + (imagename) + ".jpg"
            
            if self.images[imagename] != nil { return }
            
            Storage.storage().reference().child(userimage).getData(maxSize: 1048576) {
                (imageDataMyOutfit, Error) in
                if let Error = Error {
                    print("an error accured: " + Error.localizedDescription)
                } else {
                    if let imageDataMyOutfit = imageDataMyOutfit, let uiImage = UIImage(data: imageDataMyOutfit) {
                        DispatchQueue.main.async {
                            self.images[imagename] = uiImage
                        }
                    } else {
                        print("couldn't unwrap image data")
                    }
                }
            }
        }
    }
    
    
    struct ContentView: View {
        @StateObject var imagesLoader = ImagesLoader()
        
        var body: some View {
            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(data, id: \.id) { item in
                    VStack {
                        Text(item.displayname.capitalized)
                            .font(.title3)
                        if let uiImage = imagesLoader.images[item.user] {
                            Image(uiImage: uiImage)
                                .resizable()
                                .cornerRadius(15)
                        }
                    }
                    .onAppear{
                        imagesLoader.downloadImage(imagename: item.user)
                    }
                }
            }
        }
    }
    

    请注意,除非存在图像,否则我不会显示 Image 视图。在您当前的代码中,通过使用! 强制解开UIImage?,如果它曾经是nil,您将导致崩溃。

    另外值得指出的是,在实际情况下,您可能希望对图像进行更多缓存、错误处理等。您可以研究一个框架来执行此操作,例如 https://github.com/SDWebImage/SDWebImageSwiftUI

    【讨论】:

    • 感谢您的好评。我确实在 onAppear{} 块中收到三个错误。 (1)不能调用非函数类型'Binding'的值(2)引用下标'subscript(dynamicMember:)'需要包装'ObservedObject.Wrapper'插入($) (3)类型'的值ImagesLoader'没有使用根类型'ImagesLoader'的关键路径的动态成员'downloadimage'。我的代码中有什么问题会导致这些错误吗?还要感谢那个很棒的 github 链接。我们说话的时候我正在读它。
    • downloadImage 应该是驼峰式(大写 I 在中间)——我在原文中的错误。如果这不能解决问题,请更新您的更新代码,以便我可以确切地查看您拥有的内容。
    猜你喜欢
    • 1970-01-01
    • 2020-06-08
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    相关资源
    最近更新 更多