从firebase下载的图像未正确缩放,直到滚动表视图单元格才显示

时间:2017-01-13 20:03:13

标签: ios swift uitableview firebase-realtime-database firebase-storage

我想要发生什么:

enter image description here

实际发生的事情:

构建应用后,没有图像。

enter image description here

滚动后,请参阅下方单元格中的图像,向上滚动时,请参阅第一个单元格上的图像。

enter image description here

我做了什么:(注意:我以编程方式完成所有工作。没有故事板)

我将来自firebase数据库和firebase存储的数据加载到companies(包含名称,位置和图像的Company对象数组)。在cellAtRowAtIndexPath中,我将单元格的图像分配给companies[indexPath.row].image

公司表视图控制器

func loadData() {        
    databaseHandle = databaseRef?.child("companies").observe(.value, with: { (snapshot) in
            for item in snapshot.children.allObjects as! [FIRDataSnapshot] {
                
                                //Get image
                let id = item.childSnapshot(forPath: "id").value as! String
                let imageName = id + ".png"
                let imageRef = self.storageRef?.child(imageName)
                imageRef?.data(withMaxSize: 1 * 1024 * 1024) { data, error in
                    if let error = error {
                        print((error as Error).localizedDescription)
                    } else {
                        company.image = UIImage(data: data!)
                    }
                }
                self.companies.append(company)
                self.companyTableView.reloadData()
            }
            
        })
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
    let company = companies[indexPath.row]
    let customCell = cell as! CompanyTableViewCell
      customCell.imageView?.image = company.image
      return customCell
}

公司表格查看单元

@IBOutlet weak var companyImage: UIImageView!

override func awakeFromNib() {
        super.awakeFromNib()
          //Constraints set in .xib file. When tested, table view cell     
          properly displayed square images from assets folder
        companyImage.contentMode = .scaleAspectFit
}

公司表格查看单元格xib enter image description here

内存问题: enter image description here

1 个答案:

答案 0 :(得分:0)

自定义单元格UIImageViewCompanyTableViewCell的名称为companyImage,但是当您在cellForRowAt(_:)中为单元格设置属性时,您正在为{分配图像{1}}而不是您设置约束的自定义imageView cell.imageView?.image。我认为你正在做的是将图像设置为cell.companyImage.image中的通用UIImageView,该UITableViewCell由单元格限制,没有任何自定义约束。

要解决滚动问题,请尝试在自定义CompanyTableViewCell中创建一个如下所示的方法:

func setupCell(image: UIImage) {
    self.companyImage.image = image
}

然后在cellForRowAt(_:)方法中,不要说cell.companyImage.image = company.image,请尝试以下方法:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    // Initialize custom cell
    let company = companies[indexPath.row]
    let customCell = cell as! CompanyTableViewCell
    cell.setupCell(image: company.image)

    return cell
}

编辑:Firebase问题

您希望确保永远不会在后台线程上调用任何UI更新。另外,根据我的说法,在您的Firebase方法中,您每次进行循环时都会重新加载UITableView。这是非常低效的。只有在完成循环并在数组中附加了所有tableView.refresh()值后,才应调用company方法。一旦完成,那么你应该进行异步回调,我认为这会有效,但我不是Firebase专家

func loadData() {
    databaseHandle = databaseRef?.child("companies").observe(.value, with: { (snapshot) in
        for item in snapshot.children.allObjects as! [FIRDataSnapshot] {

            //Get image
            let id = item.childSnapshot(forPath: "id").value as! String
            let imageName = id + ".png"
            let imageRef = self.storageRef?.child(imageName)
            imageRef?.data(withMaxSize: 1 * 1024 * 1024) { data, error in
                if let error = error {
                    print((error as Error).localizedDescription)
                } else if let data = data {
                    company.image = UIImage(data: data)
                }
            }
            self.companies.append(company)
        }
        DispatchQueue.main.async {
            self.companyTableView.reloadData()
        }

    })
}

为了安全起见,先更改setupCell方法以传入可选图像,这样可以防止任何强制解包nil图像。

func setupCell(image: UIImage?) {
    self.companyImage.image = image
}