4

I'm trying to set the imageView on a standard UITableViewCell from a remote source using a placeholder. I have this issue regardless of using SDWebImage or AlamofireImage as the library.

Here is how the cell appears after the initial load:

How the image appears in the cell after the initial load

Then, once the cell has been tapped/reloaded it appears as this:

Image shrinks and moves the text when tapped/reloaded

In the storyboard, I've adjusted the row height to be 60 points instead of the standard 44 points. If I return the height to the standard 44 points, the issue is no longer present.

I believe this issue is more related to custom height of the cell rather than the library providing the placeholder. I made an issue on AlamofireImage in case it was a problem with the library but it turns out this is not the case.

How can I have the image set at the right size initially, or prevent a resize from occurring upon reload?

Here is the code from my UITableViewCell subclass. Note that the issue occurs even if I remove the frame inset code inside of layoutSubviews.

class CategoryTableViewCell: UITableViewCell {

    var category: Category! {
        didSet {
            self.updateCategory(category)
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        self.imageView?.frame = CGRectInset(self.imageView!.frame, 10, 10)
    }

    private func updateCategory(category: Category) {
        self.textLabel?.text = category.name

        self.imageView?.sd_setImageWithURL(category.largeImage ?? nil, placeholderImage: UIImage(named: "DefaultCategory"))
    }
}

I've now also set the following overrides on the table view controller, bu it hasn't had any effect.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 60;
}
    
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 60;
}
Dwight
  • 12,120
  • 6
  • 51
  • 64

3 Answers3

3

I'm using SDWebImage, and this post helped me SDWebImage fixed width cell images.

Here is my solution, just save the initial frame of the imageView, text and detailText, and restore it on the layoutSubviews()

class MoreTableViewCell: UITableViewCell {

    var imageFrame: CGRect? = nil
    var textFrame: CGRect? = nil
    var detailTextFrame: CGRect? = nil

    override func layoutSubviews() {
        super.layoutSubviews()
        if imageFrame == nil {
            imageFrame = imageView?.frame
            textFrame = textLabel?.frame
            detailTextFrame = detailTextLabel?.frame
        }

        if imageFrame != nil {
            self.imageView?.frame = imageFrame!
        }

        if textFrame != nil {
            self.textLabel?.frame = textFrame!
        }

        if detailTextFrame != nil {
            self.detailTextLabel?.frame = detailTextFrame!
        }
    }
} 
Rodrigo Gonzalez
  • 723
  • 7
  • 15
2

I would like to leave a comment but I don't have enough reputation to do so. Hence, the "answer".

I remember running into this problem before and it was due to me not setting proper constraints for it on my UITableViewCell XIB. Once I set it to a fixed width/height and pin it to the edges of the parent view, the problem resolved itself.

Rachel Fong
  • 730
  • 1
  • 8
  • 16
  • is right. If this doesn't solve your problem, then please check UIImageView content mode. – Abdul Yasin Apr 05 '16 at 06:23
  • The table view cell in my storyboard is just an empty, standard `UITableViewCell` - I'm not able to set any constraints on it as I haven't altered it by adding any subviews. – Dwight Apr 05 '16 at 08:48
  • 1
    I see. My guess here: You are accessing the default imageView in UITableViewCell where its frames are set as read-only property which in this case it is set to a default 44 points after redrawing. Refer to this link: http://stackoverflow.com/questions/18129461/uiimageview-resizes-automatically – Rachel Fong Apr 05 '16 at 10:03
  • also, @Abdul Yasin mentioned checking the content mode, that could help as well, if you do not want to go down the custom cell direction. – Rachel Fong Apr 05 '16 at 10:06
  • 1
    @rach So am I correct in understanding that the `imageView` of the default `UITableViewCell` only works at the standard height of 44 points, and if I wanted it to work at 60 points I would need to design my own view in interface builder to make it work? – Dwight Apr 05 '16 at 11:54
  • Yes. That is my assumption based on the question you described. – Rachel Fong Apr 05 '16 at 14:16
1

Just add cell.setNeedsLayout() after setting Cell's image view!

MenuController.shared.fetchImage(url: item.imageURL) { (image) in
        if let image = image {
            DispatchQueue.main.async {
                cell.imageView?.image = image
                cell.setNeedsLayout()
            }
        }
    }