首页 > 解决方案 > 为什么不显示缓存提示?

问题描述

我找到了为什么不会显示缓存提示。
如果我直接在 ContentView 上使用 ImageView,缓存提示将不会显示。
如果我用 View 包装 ImageView,然后在 ContentView 上使用包装器视图,将显示缓存提示。

这是 ContentView.swift 中的工作代码

struct ContentView: View {
    
    var links =
        [NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-0.jpg"),
         NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-1.jpg"),
         NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-2.jpg"),
         NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-3.jpg"),
         NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-4.jpg"),
         NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-5.jpg"),
         NewsItem(urlString: "https://www.jobyme88.com/wp-content/uploads/2020/11/50d0-kj-classroom-6.jpg")]
         

    var body: some View {
 
        List(links) { news in
            // working
            NewsListItemView(item: news)

            // not working 
            //NewsImageView(urlString: news.urlString)
        }
    }
}

这是 NewsListItemView,它只是一个包装器

struct NewsListItemView: View {
    var item: NewsItem
    
    var body: some View {
        NewsImageView(urlString: item.urlString)
    }
}

这是我的缓存提示位置。 NewsImageViewModel.swift

class NewsImageViewModel: ObservableObject {
    static var placeholder = UIImage(named: "NewsIcon.png")
    @Published var image: UIImage?
    var urlString: String?
    
    
    init(urlString: String) {
        self.urlString = urlString
        loadImage()
    }
    
    func loadImage() {
        if loadImageFromCache() {
            return
        }
        loadImageFromURL()
        
    }
    
    func loadImageFromCache() -> Bool {
        guard let cacheIamge = TemporaryImageCache.getShared()[urlString!] else {
            return false
        }
        print("load from cache")
        self.image = cacheIamge
        return true
    }
    
    func loadImageFromURL() {
        print("load from url")
        guard let urlString = urlString else {
            return
        }
        let url = URL(string: urlString)!
        let task = URLSession.shared.dataTask(with: url, completionHandler: getResponseFromURL(data:response:error:))
        task.resume()
        
    }
    
    func getResponseFromURL(data: Data?, response: URLResponse?, error: Error?) {
        guard error == nil else {
            print("Error \(error!)")
            return
        }
        
        guard data != nil else {
            print("No founded data")
            return
        }
        
        DispatchQueue.main.async {
            guard let loadedImage = UIImage(data: data!) else {
                print("Not supported data ")
                return
            }
            
            self.image = loadedImage
            TemporaryImageCache.getShared().cache.setObject(loadedImage, forKey: self.urlString! as NSString)
        }
        
    }
    
}

NewsImageView.swift

import SwiftUI

struct NewsImageView: View {
    @ObservedObject var model: NewsImageViewModel
    
    
    init(urlString: String) {
        model = NewsImageViewModel(urlString: urlString)
    }
    
    var body: some View {
        Image(uiImage: model.image ?? NewsImageViewModel.placeholder!)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: 100, height: 100, alignment: .center)
    }
}

NewsListItemView.swift

struct NewsListItemView: View {
    var item: NewsItem
    
    var body: some View {
        NewsImageView(urlString: item.urlString)
    }
}

这是ImageCache.swift

protocol ImageCache {
    subscript(_ urlString: String) -> UIImage? {get set }
}



struct TemporaryImageCache: ImageCache {
    subscript(urlString: String) -> UIImage? {
        get {
            cache.object(forKey: urlString as NSString)
        }
        set {
            newValue == nil ? cache.removeObject(forKey: urlString as NSString) : cache.setObject(newValue!, forKey: urlString as NSString)
        }
    }
    
    var cache = NSCache<NSString, UIImage>()

}


extension TemporaryImageCache {
    private static var shared = TemporaryImageCache()
    static func getShared() -> TemporaryImageCache {
        return shared
    }
}

这是NewsItem.swift


struct NewsItem: Identifiable {
    var id = UUID()
    var urlString: String
}

标签: swiftui

解决方案


推荐阅读