I'm using AlamofireImage to set an image on a UIImageView in a UITableViewCell like so:
cell.imageView.af_setImageWithURL(url)
The image doesn't show after downloading. It will show the image the second time when it's loaded from the memory cache.
It seems that using a placeholder image makes all the difference.
This works and prints the address of the (downloaded) image:
cell.imageView.af_setImageWithURL(URL, placeholderImage: UIImage(named: "placeholder"), filter: nil, imageTransition: .None, completion: { (response) -> Void in
print("image: \(cell.imageView.image)")
})
This doesn't work and prints "image: nil"
cell.imageView.af_setImageWithURL(URL, placeholderImage: nil, filter: nil, imageTransition: .None, completion: { (response) -> Void in
print("image: \(self.image)")
})
It also works when setting the cells imageView to an empty image before doing af_setImageWithURL:
cell.imageView.image = UIImage()
Is this a bug in UITableViewCell, AlamofireImage or am I doing something wrong?
This question is couple of years old, but maybe this answer can be useful to someone else with a similar problem, like me before to find the right solution.
Since the images are loaded asynchronously, if we didn't provide a fixed height for the UIIMageView we have to force a cell update when the download is finished. This because cell updating (i.e. AutoLayout Constraints recalculation) is done automatically only after
cellForRowAt
method, that is called when a cell is displayed for the first time, or when the table is scrolled to show other cells. In both cases probably the images are not yet downloaded by theaf_setImage()
method, so nothing but the placeholder will be displayed since their sizes are unknown for the moment.To force a cell update we need to use
beginUpdates()
andendUpdates()
methods, putting them inside the completion handler of.af_setImage()
. This way, every time the downloading is completed, the cell will be updated.But, to avoid a loop, before to call
beginUpdates()
/endUpdates()
we have to check if we have already update the cell before, because by calling these methods, thecellForRowAt
method is called again and consequently theaf_setImage()
and its completion closure withbeginUpdates()
/endUpdates()
inside it).This means that we have to update the cell only when the download is just finished, and not when the image is already cashed (because, if it is cashed, it means that we have already updated the cell). This can be accomplished by checking the response of the completion handler: if it is not
nil
, the image was just downoladed, if it isnil
, the image was cashed.As a side benefit the cell height will be automagically adjusted (remember to put
tableView.estimatedRowHeight = 400
andtableView.rowHeight = UITableViewAutomaticDimension
in yourviewDidLoad()
method)Finally, here it is the code:
That's all folks! ;-)
You can print the error by adding 2 line of code so that you will get more Idea about the issue.
In my case there was an issue with Image URL. It was downloading the image when I open it in browser.