首页 > 解决方案 > 显示来自 firebase / Swift 的图像

问题描述

我正在尝试从数据库中调用图像以显示在 tableView 中。当我从详细视图进出时它会出现,但在我第一次启动时不会出现。

这是我的代码。

//ImageStore扩展类(firebase使用)

class ImageStoreWithFirebase: ImageStore{

    var reference: StorageReference
    override init(){
        reference = Storage.storage().reference().child("imageStore")
        
        super.init()
    }
    
    override func setImage(image: UIImage, forKey key: String) {
        super.setImage(image: image, forKey: key)
        
        let data = image.jpegData(compressionQuality: 1.0)!
        reference.child(key).putData(data)
    }
    
    override func imageForKey(key: String) -> UIImage? {
        if let image = super.imageForKey(key: key){
            return image
        }
        
        reference.child(key).getData(maxSize: 10*1024*1024, completion: {
            (data,error) in
            if error == nil {
                if let image = UIImage(data: data!){
                    self.setImage(image: image, forKey: key)
                }
            }
        })
        return nil
    }
    
    override func deleteImage(key: String) {
        super.deleteImage(key: key)
        reference.child(key).delete(completion: nil)
    }
}

为图像设置、删除、getKey 的类

class ImageStore: NSObject{
    let cache = NSCache<AnyObject, AnyObject>()
    
    func setImage(image: UIImage, forKey key: String){
        cache.setObject(image, forKey: key as AnyObject)
    }
    
    func imageForKey(key: String) -> UIImage? {
        return cache.object(forKey: key as AnyObject) as? UIImage
    }
    
    func deleteImage(key: String){
        cache.removeObject(forKey: key as AnyObject)
    }
}

实际的视图控制器类

class ItemsViewController: UIViewController {
    var itemStore: ItemStore!
    var imageStore: ImageStore!
    
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        
        (itemStore as! ItemStoreWithFirebase).setListener{
            (notifyAction : ItemStoreWithFirebase.NotifyAction, index: Int) in
            
            let indexPath = IndexPath(row: index, section: 0)
            if notifyAction == .added {
                self.tableView.insertRows(at: [indexPath], with: .automatic)
            }
            if notifyAction == .removed{
                self.tableView.deleteRows(at: [indexPath], with: .automatic)
            }
            if notifyAction == .modified{
                self.tableView.reloadRows(at: [indexPath], with: .automatic)
            }
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        tableView.reloadData()
        navigationItem.title = "Home page"
    }
    
    @IBAction func addNewItem(_ sender: AnyObject) {
        
        let newItem = Item(random: true)
        itemStore.addItem(item: newItem)

//        if let index = itemStore.allItems.index(of: newItem){
//            let indexPath = IndexPath(row: index, section: 0)
//            tableView.insertRows(at: [indexPath], with: .automatic)
//        }
        
    }
    
    @IBAction func toggleEditingMode(_ sender: UIBarButtonItem) {
        if tableView.isEditing {
            sender.title = "Edit"
            tableView.setEditing(false, animated: true)
        }else{
            sender.title = "Done"
            tableView.setEditing(true, animated: true)
        }
        
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowItem" {
            if let row = tableView.indexPathForSelectedRow?.row {
                let item = itemStore.allItems[row]
                let detailViewController = segue.destination as! DetailViewController
                detailViewController.item = item
                detailViewController.imageStore = imageStore
                detailViewController.itemStore = itemStore
            }
        }
    }
}

extension ItemsViewController: UITableViewDelegate, UITableViewDataSource{
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemStore.allItems.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
        let item = itemStore.allItems[indexPath.row]

        cell.textLabel!.text = item.name
        cell.detailTextLabel?.text = String(item.valueInDollars)
        cell.imageView!.image = imageStore.imageForKey(key: item.itemKey)
        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            let alertController = UIAlertController(title: "삭제", message: "정말로 삭제하나요?", preferredStyle: .alert)
            let yesAlertAction =  UIAlertAction(title: "Yes", style: .default){
                (action) in

                let item = self.itemStore.allItems[indexPath.row]
                self.imageStore.deleteImage(key: item.itemKey)
                self.itemStore.removeItem(key: item.itemKey)
                //self.tableView.deleteRows(at: [indexPath], with: .automatic)
            }

            let noAlertAction = UIAlertAction(title: "No", style: .cancel, handler: nil)
            alertController.addAction(yesAlertAction)
            alertController.addAction(noAlertAction)

            present(alertController, animated: true, completion: nil)
        }
    }
    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        itemStore.moveItem(from: sourceIndexPath.row, to: destinationIndexPath.row)
        tableView.reloadData()
    }
}

虽然它很简单,但我不能只是找到解决这个问题的方法。对不起,因为我来自非英语国家,所以我的英语技能不足。

谢谢。

标签: iosswiftfirebasefirebase-storage

解决方案


推荐阅读