tableViewCellアダプティブピクチャ高さiOS

2230 ワード

普段tableViewCellの適応が高いときはcellのコントロールに上下の制約をしておけば良いのですが、cellが純画像であれば上下の制約をするだけでは足りません.画像自体の高さを取得してcellのheightに割り当てる必要があります.
cell上の画像の多くはネットワークでロードされていますが、バックグラウンドで各画像に対応する高さを返すと、私たちは直接持ってきて使用することができます.しかし、画像だけを返すには、私たち自身がその高さを得る必要があります.私がここで使っているのはSDWebImageで、画像をロードした後にimageに戻り、その時に彼の幅を得ることができます.
主なサンプルコード:カスタムcellでblockをcontrollerに返す
typedef void(^GetImageHeight)(CGFloat height);
@property (nonatomic, copy) GetImageHeight getImageHeight;
- (void)setImgStr:(NSString *)imgStr{
    [_imgV sd_setImageWithURL:[NSURL URLWithString:kGoodsImageUrl(imgStr)] placeholderImage:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        if (image.size.height>0) {
            CGFloat scale =  (kScreenWidth-20)/image.size.width;
            CGFloat scaleHeight = image.size.height*scale;
            //     controller
            self.getImageHeight(scaleHeight);
        }
    }];
}

コントローラで画像を格納する高さを定義する辞書
@property (nonatomic, strong) NSMutableDictionary *imageHeightArray;

cellが返すピクチャの高さを取得する
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    MallInfoTextCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MallInfoTextCell class])];    
    cell.getImageHeight = ^(CGFloat height) {
        if (![[self.imageHeightArray allKeys] containsObject:@(indexPath.row)]) {
            [self.imageHeightArray setObject:@(height) forKey:@(indexPath.row)];
            [self.tableView beginUpdates];
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
            [self.tableView endUpdates];
        }
    };
    cell.imgStr = _infoImgArr[indexPath.row];
    return cell;
}

最後に各cellに高い値を割り当てます
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat height = [[self.imageHeightArray objectForKey:@(indexPath.row)] floatValue];
    if (height>0) {
        return height;
    }
    //          ,      
    return 200;
}