1

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

Cœur
  • 37,241
  • 25
  • 195
  • 267
user3057944
  • 701
  • 1
  • 8
  • 19
  • I have to say that your project is quite confusing. Why are you using a content view with stack view inside the cell ? didn't get it. Try to follow this tutorial, it is very simple and straight forward to do what you need. https://www.appcoda.com/customize-table-view-cells-for-uitableview/ – GIJOW Jan 23 '18 at 16:00
  • @GIJOW whats the problem with the `UIStackView`? that's the way I would do it.. – Milan Nosáľ Jan 23 '18 at 16:03
  • Did not say problem, did say confusing. I would not do like it. Maybe why I found it confusing – GIJOW Jan 23 '18 at 16:05
  • Thanks for the answers, I'd like to try out to make layouts with stack view and with constraints. At first I implemented it with the stack view. @GIJOW I'll check out your link. – user3057944 Jan 23 '18 at 20:36

1 Answers1

1

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.

Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
  • Thank you very much! I don't have time now, but I tried it, it works perfectly. I'll read your answer. – user3057944 Jan 23 '18 at 16:30
  • @user3057944 would you mind leaving an upvote on the original answer then? thanks – Milan Nosáľ Jan 23 '18 at 16:30
  • sorry :S forgot it. – user3057944 Jan 23 '18 at 16:33
  • @user3057944 I meant the one that I provided link to, but thanks anyway :D – Milan Nosáľ Jan 23 '18 at 16:34
  • Oh, I see! I woted iti also. – user3057944 Jan 23 '18 at 20:34
  • Well, I just was able to try your solution just now more closely, and I noticed as I scrolled the list, it was messy. So I replaced beginupdates-endupdates with cell.setNeedsLayout() and it works well, the keypoint was to call it from the callback. My only problem, the images are still overlaps the content of the cell, and I can't find out why, as you can read in my updated post. So many thanks for your help, but I you could be help find out why does it happen it would be really nice. – user3057944 Jan 23 '18 at 23:18
  • I would like to request you to go for Custom cell approach. You can create a custom cell using nib. Design the custom cell and register this nib for the tableview. – KGen Jan 23 '18 at 23:23
  • @user3057944 what do you mean by "it was messy"? can you share the relevant code, preferably as a minimal working example project? – Milan Nosáľ Jan 24 '18 at 06:47
  • @MilanNosáľ I made a public Bitbucket repo. Please check it out. https://mkravd@bitbucket.org/mkravd/learnios.git – user3057944 Jan 24 '18 at 10:15
  • @user3057944 seems that the repository is not public, it asks for credentials – Milan Nosáľ Jan 24 '18 at 10:19
  • @MilanNosáľ sorry, I left the username in the link. This is the correct. https://bitbucket.org/mkravd/dpn.git – user3057944 Jan 24 '18 at 10:28
  • @user3057944 still access denied – Milan Nosáľ Jan 24 '18 at 10:30
  • @MilanNosáľ I shared a wrong repo without username. So this is the good repo. bitbucket.org/mkravd/learnios.git – user3057944 Jan 24 '18 at 11:09
  • @user3057944 ok, I got to it.. I dont have time right now, but in the evening I'll take a look at it for you.. – Milan Nosáľ Jan 24 '18 at 11:42
  • @user3057944 at this link you will find working solution: https://drive.google.com/open?id=1XxZStcNUl48UdIq4U2vFjJLcG71CKJAB – Milan Nosáľ Jan 24 '18 at 21:59
  • @user3057944 I had to drop the storyboards, you tried to implement a common base class for both cells, but that messed up your UI - I don't know if and how inheritence in storyboards work, but I don't use storyboards and hopefully never will, research it for yourself. anyway, go over the code and try to understand it.. there are two points that I implemented there but havent mentioned before - first, now I "cache" image height and use an explicit height constraint for imageView, second, prepareForReuse is used to cancel download (if download did not end before the cell was presented) – Milan Nosáľ Jan 24 '18 at 22:05
  • @MilanNosáľ thanks a lot, I'll check your code tomorrow. At the rest of the day I was able to implement a view pager controller, but now I'm tired a little bit. Anyway every advice is good for me, I've been developing Android for about five years, but ios world is a bit different. Thanks once more! – user3057944 Jan 24 '18 at 22:25