动态TableViewCell高度以适合下载的图像

Chr*_*sco 6 objective-c uitableview ios

我正在回答这个问题:在UITableView中使用自动布局来获得动态单元格布局和可变行高,但它缺少两件让我无法完成它的事情:

  1. 我在Storyboard原型单元格中设置了约束,而不是以编程方式
  2. 图像下载完成异步.

基本上我正在下载图像SDWebImage,并调整其UIImageView高度,以便显示整个图像(当然按比例缩小).我遇到的问题在下面的代码中得到了评论:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   // dequeue cell using identifier

  [cell.pictureView sd_setImageWithUrl:myUrl completed:^( ... block ...) {

       // This code will scale down the UIImage to the UIImageView's width maitaining
       // its aspect ratio, and also will resize the UIImageView's to match the scaled-down UIImage's height

       if(image != nil) {
         CGSize imageSize = [image size];
         CGSize imageViewSize = CGSizeMake(280.0, 100.0);

         CGFloat correctHeight = (imageViewSize.width / imageSize.width) * imageSize.height;

         [[cell pictureView] setFrame:CGRectMake([[cell pictureView] frame].origin.x,
                                                  [[cell pictureView] frame].origin.y,
                                                  CGRectGetWidth([[cell pictureView] bounds]),
                                                  correctHeight)];

           // At this point, the subviews are all set. Since this happens async, what method do I call to re-calculate this row's height.

  }];


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    static int defaultHeight = 230;

    // Get's the offscreen cell used only for calculation purposes
    WKZEventsCell *cell = [[self offscreenCells] objectForKey:CellIdentifier];
    if(!cell) {

        // HOW DO I GET A REFERENCE TO A PROTOTYPED CELL INSIDE THE STORYBOARD??? 
        // note that calling dequeueReusableCellWithIdentifier:CellIdentifier will cause a memory leak      

        cell = ??????
        [[self offscreenCells] setObject:cell forKey:CellIdentifier];
    }

    WKZEvent *event = [[self eventList] objectAtIndex:[indexPath row]];
    [[cell titleLabel] setText:[event title]];
    [[cell placeLabel] setText:[event title]];
    [[cell pictureView] setImage:image];


    // Even tho this should be in memory cache right now, I'm pretty sure this call is still asynchronous, so this might make the whole thing wont work.
    [cell.pictureView sd_setImageWithUrl:myUrl


    // THIS METHODS ARE COMMENTED BECAUSE MY CONSTRAINTS ARE SET IN STORYBOARD, BUT NOT SURE IF I'M RIGHT AT THIS ONE
    //[cell setNeedsUpdateConstraints];
    //[cell updateConstraintsIfNeeded];

    // I DONT HAVE A MULTILINE LABEL SO I DONT CALL THIS. NOT SURE ABOUT THIS ONE EITHER
    //cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

    [cell setNeedsLayout];
    [cell layoutIfNeeded];

    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    height += 1;

    NSLog(@"%f", height);

    return height;
}
Run Code Online (Sandbox Code Playgroud)

Rud*_*vič 8

故事板:

  • 在表视图中添加一个新单元格
  • 将新图像视图添加到单元格
  • (可选)为图像视图设置占位符图像
  • 让细胞的约束明确地描述它的高度

务必将单元格的行高保留为默认值

码:

使表格视图自我调整大小:

var tableview: UITableView {
    didSet {
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 44
    }
}
Run Code Online (Sandbox Code Playgroud)

在运行时,尽快开始异步加载图像.

下载后,将图像加载到图像视图并执行:

tableView.beginUpdates()
tableView.endUpdates()
Run Code Online (Sandbox Code Playgroud)