ios – Display Images table view controller with AlamofireImage Swift 2 Library

Question:

I am making an app that works as a feed reader.

I have a UITableViewController , in which I show all the news that I read from an xml, I show the title, the date, a short description and an image. Except for the image, everything is correct.

I have added the AlamofireImage library to display the images. At first they don't appear, but if I reloadData() the view with a reloadData() , the images appear.

Most of the images are viewed in their correct position, but others are out of position and in some, only an image is output. The title, date and description do not appear.

If I put a fixed width and height on the images, it appears perfectly, but if I only position them due to constraints, it is when the error appears, which takes time to load.

I leave you the code that I use:

if let actualImageView = imageView {
// actualImageView.load(currentArticleToDisplay.imagen)
/*let url:NSURL? = NSURL(string:currentArticleToDisplay.imagen)
    let imageRequest = NSURLRequest(URL: url!)
    NSURLConnection.sendAsynchronousRequest(imageRequest, queue: NSOperationQueue.mainQueue(), completionHandler: {(response, data, error) in
    actualImageView.image = UIImage(data: data!)
    //actualImageView.contentMode = UIViewContentMode.ScaleAspectFit
  })*/
  actualImageView.contentMode = .ScaleAspectFit

  let URL = NSURL(string: currentArticleToDisplay.imagen)!

  actualImageView.af_setImageWithURL(
     URL,
     placeholderImage: nil,
     filter: nil
  )
  //actualImageView.frame = view.bounds
  //actualImageView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

  //actualImageView.contentMode = UIViewContentMode.ScaleAspectFit
}

The constraints, I have them defined in the Main.storyboard , because if I put them in code, they didn't load me at first either.

Any idea what the problem may be? Do I need to add more parts of the code? Is this the correct way to display images? Is there a library with which I can solve it?

Thanks!

Answer:

Using AlamofireImage is correct, just that you are not taking into account that the requests are made asynchronously ; that's why the first time the images 'don't appear' as they haven't finished loading yet when you invoke:

if let actualImageView = imageView {
    // ...
}

Which obviously returns nil and is not done until you re-execute reloadData() , which on the other hand, it is not even necessary to manually update the table with reloadData() since AlamofireImage updates the UIImageView when it has finished downloading it.

I am not sure where you are assigning the image so I will assume that you do it in the delegate method cellForRowAtIndexPath , hence I share the following sample code that does what you want with Dummy content:

import UIKit
import AlamofireImage

class DummyCell: UITableViewCell {
    @IBOutlet weak var myAwesomeImage: UIImageView!
    @IBOutlet weak var myAwesomeLabel: UILabel!
}

class MyAwesomeTableViewController: UITableViewController {

    let numberOfCells: Int = 100

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numberOfCells
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! DummyCell
        cell.myAwesomeLabel.text = "My awesome label \(indexPath.row)"

        let imageURL = NSURL(string: "http://placehold.it/100?text=Image%20\(indexPath.row)")!

        cell.myAwesomeImage.contentMode = .ScaleAspectFit
        cell.myAwesomeImage.af_setImageWithURL(imageURL, placeholderImage:nil)

        return cell
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 100
    }
}

When the images finish downloading, they will be displayed in the assigned place. You could also substitute:

cell.myAwesomeImage.af_setImageWithURL(imageURL, placeholderImage:nil)

for

let placeHolder = UIImage(named: "placeHolder.png")
cell.myAwesomeImage.af_setImageWithURL(imageURL, placeholderImage:placeHolder)

Where "placeHolder.png" is an image that you would have in your project and that will be displayed while the actual images finish downloading.

Scroll to Top