How to auto-layout the UIImageview base on its ima

2019-06-07 16:23发布

问题:

I built a sample project hosted on GitHub.

There is a table view and its custom cell has a multiple line UILabel and a dynamic image view base on its image size. I built it step by step to verify the auto-layout issue on the custom cell.

In the 3rd sample table view (Table3ViewController) which has the above view structure, I tested it with sample random length text and local images. It succeeds, just like Apple documentation and this thread said.

Actually, all the auto-layout tutorials or examples from google search results are tested base on the local image assets, no SDWebImage usage related, basically.

In Table4ViewController, the UIImageView/UITableViewCell(CustomCell) finished its subview's layout before the SDWebImage set the final image object to UIImageView asynchronously.

Here is my question, how to re-layout the UITableViewCell(CustomCell) after the SDWebImage downloaded the image from the network?

Here are my constraints within CustomCell.

    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.top);
        make.centerX.width.equalTo(self.contentView);
        make.bottom.equalTo(imageView.top);
        make.height.greaterThanOrEqualTo(@16);
    }];

    [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(label.bottom);
        make.bottom.equalTo(self.contentView.bottom);
        make.centerX.width.equalTo(self.contentView);
        make.height.lessThanOrEqualTo(@200);
    }];

I tried to move the implementation to initWithStyle:reuseIdentifier: or updateConstraints or layoutSubviews method, all the results are the same and failed.

Here is the image view assignment within cellForRow without placeholder image.

__weak __typeof(cell) weakCell = cell;

[cell.theImageView sd_setImageWithURL:[NSURL URLWithString:dict.allValues.firstObject]
                            completed:^(UIImage *_Nullable image, NSError *_Nullable error, SDImageCacheType cacheType, NSURL *_Nullable imageURL) {
      __strong __typeof(cell) strongCell = weakCell;

      [strongCell setNeedsUpdateConstraints];
      [strongCell updateConstraintsIfNeeded];
}];

Assume a network image has size 400x400 points, there is no reserved placeholder image in cell, the update constraint and layout subviews' request will be ready and finished asynchronously successfully. However, the new cell's height won't be recalculated into the contentSize of tableview, the draw process of CustomCell won't be called. It fails.


Here is the image view assignment within cellForRow with placeholder image.

__weak __typeof(cell) weakCell = cell;

[cell.theImageView sd_setImageWithURL:[NSURL URLWithString:dict.allValues.firstObject]
                     placeholderImage:GetImageWithColor(DarkRandomColor, CGRectGetWidth(tableView.frame), 400)
                            completed:^(UIImage *_Nullable image, NSError *_Nullable error, SDImageCacheType cacheType, NSURL *_Nullable imageURL) {
      __strong __typeof(cell) strongCell = weakCell;

      [strongCell setNeedsUpdateConstraints];
      [strongCell updateConstraintsIfNeeded];
}];

The final image will be drawn with the same size of reserved placeholder image finally, but I expected the final image's size even specified ratio.

So, how to re-layout the image view's size constraint after downloading the image asynchronously?

Please help, thanks!