I have a code where I am fetching images from URLs and displaying them in a tableview, however the images only show up inside tableview when scrolling down to far bottom of the screen, as show in the image below.
TableView before scrolling to bottom, screenshot
TableView after scrolling to bottom, screenshot
Code for the fetching images and tableView
@IBOutlet weak var tableView: UITableView!
let imageArray = [UIImage()]
let urlArray = ["https://media.api-sports.io/football/teams/50.png","https://media.api-sports.io/football/teams/47.png","https://media.api-sports.io/football/teams/49.png","https://media.api-sports.io/football/teams/46.png","https://media.api-sports.io/football/teams/48.png"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(UINib(nibName: "ImageCell", bundle: nil), forCellReuseIdentifier: "imageCell") // Do any additional setup after loading the view.
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageCell
cell.clubImage.load(url: URL(string: urlArray[indexPath.row])!)
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return urlArray.count
}
}
extension UIImageView {
func load(url: URL) {
DispatchQueue.global().async { [weak self] in
if let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
DispatchQueue.main.async {
self?.image = image
}
}
}
}
}
}
How can I show the images as soon as the app loads?
Thanks
CodePudding user response:
The issue is that the table view is calculating the size of the cell before an image has been loaded. The image view in the cell defaults to a height of zero since it has no content yet. I'd suspect something in the table view implementation causes the cells sizes to be recalculated when reaching the bottom which allows them to appear.
One solution could be to add a constraint to the image view so that it has a fixed size before an image is loaded. The simplest is if all cells can have the same size. If they need different sizes, that would need to be set in cellForRowAt
either before loading the image, or the image loading would need to be moved so it's done outside of the cell allowing the cell to be reloaded with the correct size later.
CodePudding user response:
Make your load method with completion:
func load(url: URL, completion: @escaping (UIImage?) -> Void) {
DispatchQueue.global().async { in
if let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
DispatchQueue.main.async {
completion(image)
}
}
}
}
}
Then in cellForRawAt call the method and add your loaded imaged to your imageView:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageCell
cell.clubImage.load(url: URL(string: urlArray[indexPath.row])!) { image in
// display your image here...
}
return cell
}