我想要发生什么:
实际发生的事情:
构建应用后,没有图像。
滚动后,请参阅下方单元格中的图像,向上滚动时,请参阅第一个单元格上的图像。
我做了什么:(注意:我以编程方式完成所有工作。没有故事板)
我将来自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
}
答案 0 :(得分:0)
自定义单元格UIImageView
中CompanyTableViewCell
的名称为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
}