Search code examples
iosuitableviewswift4xcode9

iOS load image into table view cell


update

now images displays as they are loaded, but there still a problem I can't solve. The images overlaps the content of the cell even the three views are in a vertical stack (first is the image, the next two are label views). I wonder how can a view overlap other views in a stackview

imageview overlaps label views

now my talbe view delegate method looks like this:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell: BaseTableViewCell!
    if let contents = contents {
        let content = contents[indexPath.row]
        if let imageUrl = content.imageUrl, let url = URL(string: imageUrl) {
            cell = tableView.dequeueReusableCell(withIdentifier: "ImageContentRow", for: indexPath) as! ContentWithImageTableViewCell
            Alamofire.request(url).responseImage(completionHandler: { (response) in
                if let image = response.result.value {
                    cell.imageView?.image = image
                    cell.setNeedsLayout()
                }
            })
        }else{
            cell = tableView.dequeueReusableCell(withIdentifier: "ContentRow", for: indexPath) as! ContentTableViewCell
        }
        cell.contentTitleVeiw.text = content.title
        cell.contentLeadView.text = content.lead
    }
    return cell!
}

I'm very new to iOS. I've already tutorials and watched video courses and now I would like to implement my very first app. I try to read a feed and display the content's title, lead and image (if it has any). I defined a cell, with an UIMageVeiw, and two UILables, at last I embedded them into a vertical StackView (I set distribution to Fill). Everything works well, but images don't display automatically, just if I click on the cell, or sroll the TableVeiw. And even if I set the image view to Aspect Fit (and embedded it into the top tof the vertical stack view), when the image displays it keeps it's original size and overlaps the cell content. I've trying to find out what I do wrong for two days, but I can't solve it.

I try display data like this:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell: BaseTableViewCell!
    if let contents = contents {
        let content = contents[indexPath.row]
        if let imageUrl = content.imageUrl, let url = URL(string: imageUrl) {
            cell = tableView.dequeueReusableCell(withIdentifier: "ImageContentRow", for: indexPath) as! ContentWithImageTableViewCell
            cell.imageView?.af_setImage(withURL: url)
        }else{
            cell = tableView.dequeueReusableCell(withIdentifier: "ContentRow", for: indexPath) as! ContentTableViewCell
        }
        cell.contentTitleVeiw.text = content.title
        cell.contentLeadView.text = content.lead
    }
    return cell!
}

The image view cell's view hierarchy looks like this:

ImageContentCell

My list looks like this after I start my app and data displayed:

After data loaded

After I click on a cell that should display an image or scroll it out and back the result is this:

After click or scroll

At least this is my list view controller with the two prototype cells (one for contents with image, one for without image)

table controller


Solution

  • You need to notify the tableView that the image was loaded and that it has to redraw the cell.

    Try changing

    cell.imageView?.af_setImage(withURL: url)
    

    to

    cell.imageView?.af_setImage(withURL: url, completion: { (_) in
        self.tableView.beginUpdates()
        self.tableView.setNeedsDisplay()
        self.tableView.endUpdates()
    })
    

    Take a look at my answer here - in the end you might need to explicitly set height on the imageView.