在异步加载时设置动画 cell.imageview
Animate cell.imageview on async load
我正在尝试做一个 table,当图像完成加载(异步)时,单元格上的 imageView 会将 alpha 从 0 更改为 1。
无论我做什么,图像似乎都只显示一个,而不是淡入。我确定这是某种竞争条件,但我是 iOS 中的动画新手,不知道如何解决这个问题。任何输入都会很棒。
这是我的代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
//Configure the cell...
let episode = episodes[indexPath.row]
cell.textLabel?.text = episode.title
cell.detailTextLabel?.text = episode.content
let logoUrl = URL(string: episode.logoUrl!)
if (episode.logoImage == nil){
episode.logoImage = UIImage()
DispatchQueue.global().async {
let data = try? Data(contentsOf: logoUrl!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
DispatchQueue.main.async {
episode.logoImage = UIImage(data: data!)
cell.imageView?.image = episode.logoImage
self.episodesTable.reloadData()
cell.imageView?.alpha = 0
UIView.animate(withDuration: 1, animations: {
cell.imageView?.alpha = 1
})
}
}
} else{
cell.imageView?.image = episode.logoImage
}
return cell
}
您需要先将 alpha 设置为 0,然后再设置为 1。
cell.imageView?.alpha = 0
UIView.animate(withDuration: 1, animations: {
cell.imageView?.alpha = 1
})
此外,您不需要重新加载 table。删除 self.episodesTable.reloadData()
.
您正在跨后台线程并在该线程中从 url 加载图像。如果在用户滚动单元格之间怎么办。您会在错误的单元格上留下错误的图像(这是因为单元格重用)。
我的建议是使用 SDWebImageCache,并使用其完成块为 alpha 设置动画。
// Changing animation duration to 0.2 seconds from 1 second
if(cacheType == SDImageCacheTypeNone) {
cell.imageView?.alpha = 0
[UIView animateWithDuration:0.2 animations:^{
cell.imageView?.alpha = 1;
}];
}
reloadData()
调用导致重新加载所有单元格,包括您尝试设置动画的单元格。我的建议是用它的索引路径标记你的单元格。异步调用后检查它是否仍然呈现正确的数据并在不重新加载整个 table 视图的情况下对其进行动画处理。
// ...
cell.tag = indexPath.item
DispatchQueue.global().async {
// async load
DispatchQueue.main.async {
guard cell.tag == indexPath.item else { return }
cell.imageView?.alpha = 0.0
cell.imageView?.image = image
// animate
}
}
// ...
我正在尝试做一个 table,当图像完成加载(异步)时,单元格上的 imageView 会将 alpha 从 0 更改为 1。 无论我做什么,图像似乎都只显示一个,而不是淡入。我确定这是某种竞争条件,但我是 iOS 中的动画新手,不知道如何解决这个问题。任何输入都会很棒。 这是我的代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
//Configure the cell...
let episode = episodes[indexPath.row]
cell.textLabel?.text = episode.title
cell.detailTextLabel?.text = episode.content
let logoUrl = URL(string: episode.logoUrl!)
if (episode.logoImage == nil){
episode.logoImage = UIImage()
DispatchQueue.global().async {
let data = try? Data(contentsOf: logoUrl!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
DispatchQueue.main.async {
episode.logoImage = UIImage(data: data!)
cell.imageView?.image = episode.logoImage
self.episodesTable.reloadData()
cell.imageView?.alpha = 0
UIView.animate(withDuration: 1, animations: {
cell.imageView?.alpha = 1
})
}
}
} else{
cell.imageView?.image = episode.logoImage
}
return cell
}
您需要先将 alpha 设置为 0,然后再设置为 1。
cell.imageView?.alpha = 0
UIView.animate(withDuration: 1, animations: {
cell.imageView?.alpha = 1
})
此外,您不需要重新加载 table。删除 self.episodesTable.reloadData()
.
您正在跨后台线程并在该线程中从 url 加载图像。如果在用户滚动单元格之间怎么办。您会在错误的单元格上留下错误的图像(这是因为单元格重用)。
我的建议是使用 SDWebImageCache,并使用其完成块为 alpha 设置动画。
// Changing animation duration to 0.2 seconds from 1 second
if(cacheType == SDImageCacheTypeNone) {
cell.imageView?.alpha = 0
[UIView animateWithDuration:0.2 animations:^{
cell.imageView?.alpha = 1;
}];
}
reloadData()
调用导致重新加载所有单元格,包括您尝试设置动画的单元格。我的建议是用它的索引路径标记你的单元格。异步调用后检查它是否仍然呈现正确的数据并在不重新加载整个 table 视图的情况下对其进行动画处理。
// ...
cell.tag = indexPath.item
DispatchQueue.global().async {
// async load
DispatchQueue.main.async {
guard cell.tag == indexPath.item else { return }
cell.imageView?.alpha = 0.0
cell.imageView?.image = image
// animate
}
}
// ...