farhan
farhan

Reputation: 233

How to set different UITableViewCell heights based on the UIImageView height?

I need to set the height for the Cells based on the height of the uiimageview which is scaledHeight variable im getting images from Parse like so in my cellForRowAtIndexPath

PFFile *userImageFile = object[@"image"];
    [userImageFile getDataInBackgroundWithBlock:^(NSData * _Nullable data, NSError * _Nullable error) {
        if (!error) {
           // UIImageView *imageView = (UIImageView *)[cell viewWithTag:1];
            UIImage *image = [UIImage imageWithData:data];
           // imageView.image = image;


            UIImageView *test = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 400, 320)];
            test.image = image;

            CGSize imgSize = image.size;
            CGFloat ratio = test.frame.size.width/imgSize.width;
            CGFloat scaledHeight = imgSize.height * ratio;

            [test setFrame:CGRectMake(0, 0, self.view.window.frame.size.width, scaledHeight)];

            NSLog(@"HEIGHT:%f",scaledHeight);

            [cell addSubview:test];

        }
    } progressBlock:^(int percentDone)
    {

    }];

how can i set scaledHeight inside heightForRowAtIndexPath as heightForRowAtIndexPath is run before CellForRowAtIndexPath?

Upvotes: 1

Views: 1071

Answers (5)

ios developer
ios developer

Reputation: 198

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //This is for same height of image view
     uitableViewCell *cell = [tableView cellforRowAtIndexPath : indexPath];
     return cell.imageView.size.height;
   //If you have different sizes of images then store all those image in array and then calculate the height.

}

Upvotes: 1

Kiran Jasvanee
Kiran Jasvanee

Reputation: 6554

Get the image size bounds height and return it on heightForRowAtIndexPath. That will dynamically differ your height according to your image height size.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
   //Assign your url
   NSURL* aURL = [NSURL URLWithString:@"URL"];

   //get data of that url image.
   NSData* data = [[NSData alloc] initWithContentsOfURL:aURL];

   //get image 
   UIImage *image = [UIImage imageWithData:data];

   //return it's bounding height (bounds return the area of height image requires.)
   return image.bounds.height;  
}

Upvotes: 0

darshan
darshan

Reputation: 1115

1. Try to set default heights in Array

- (void)setDefaultRowHeights {
    self.imageHeights = [NSMutableArray arrayWithCapacity:self.imageURLs.count];
    for (int i = 0; i < self.imageURLs.count; i++) {
        self.imageHeights[i] = @(self.tableView.rowHeight);
    }
}

2. In cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    NSString *imageURL = self.imageURLs[indexPath.row];
    __weak TableViewCell *weakCell = cell;
    __weak typeof(self) weakSelf = self;
    [cell.mainImageView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]]
                              placeholderImage:[UIImage new]
                                       success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                                           weakCell.mainImageView.image = image;

                                          // Calculate Heights
                                           NSInteger oldHeight = [weakSelf.imageHeights[indexPath.row] integerValue];
                                           NSInteger newHeight = (int)image.size.height;

                                           // Update table row height if image is in different size
                                           if (oldHeight != newHeight) {
                                               weakSelf.imageHeights[indexPath.row] = @(newHeight);
                                               [weakSelf.tableView beginUpdates];
                                               [weakSelf.tableView endUpdates];
                                           }
                                       } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                                           NSLog(@"Error:");
                                       }];

    return cell;
}

3. In heightForRowAtIndexPath

   - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return [self.imageHeights[indexPath.row] integerValue];
    }

Upvotes: 1

Jaydeep Patel
Jaydeep Patel

Reputation: 1739

Take one mutablearray(NSMutableArray *arrayHeights) by default this array has number of object equal to total number of rows. and they all have set "0" value

and heightForRowAtIndexPath return

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return   [arrayHeights[indexPath.row] floatValue] + 50.0; // 50 is default space set it according your requirements  
}

now when you get result from getDataInBackgroundWithBlock replace object of arrayHeights with image height for that particular index and reload that cell

PFFile *userImageFile = object[@"image"];
    [userImageFile getDataInBackgroundWithBlock:^(NSData * _Nullable data, NSError * _Nullable error) {
        if (!error) {
           // UIImageView *imageView = (UIImageView *)[cell viewWithTag:1];
            UIImage *image = [UIImage imageWithData:data];
           // imageView.image = image;


            UIImageView *test = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 400, 320)];
            test.image = image;

            CGSize imgSize = image.size;
            CGFloat ratio = test.frame.size.width/imgSize.width;
            CGFloat scaledHeight = imgSize.height * ratio;
            [arrContactList replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithFloat:scaledHeight]];
            [test setFrame:CGRectMake(0, 0, self.view.window.frame.size.width, scaledHeight)];

            NSLog(@"HEIGHT:%f",scaledHeight);

            [cell addSubview:test];
// reload cell
        }
    } progressBlock:^(int percentDone)
    {

    }];

Upvotes: 0

Aruna Mudnoor
Aruna Mudnoor

Reputation: 4825

Since you are loading image asynchronously by default you have to return some default value in heightForRowAtIndexPath method. Once image gets loaded you have to reload only that particular row. Now again heightForRowAtIndexPath will be called there you have return actual height of the image. You can also add some animation while reloading particular row, so that UI transition will be smooth.

Upvotes: 1

Related Questions