TechChain
TechChain

Reputation: 8952

How to get cell in heightForRowAtIndexPath?

I have created custom cells in my app.I want to get the each cell in HeightForRowAtIndexPath.Please tell me how can i get the custom cell in this method.I have tried this code but this causes infinite loop & finally crash the app.

HomeCell *cell=(HomeCell *)[tableView cellForRowAtIndexPath:indexPath];

EDIT:

I Have tried this but it gives me cell height as zero.

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

    static NSString *cellIdentifier = @"HomeCell";
    HomeCell *cell = (HomeCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    float tv_view_height=cell.tv_post.frame.size.height;
    float like_count_height=cell.label_like_count.frame.size.height;
    float first_comment_height=cell.first_comment.frame.size.height;
    float second_comment_height=cell.second_cmment.frame.size.height;
    float third_comment_height=cell.third_comment.frame.size.height;

    Post *user_post=[arr_post objectAtIndex:indexPath.row];
    float comment_count=[user_post.comment_count intValue];
    if(comment_count<=0)
    {
        first_comment_height=0;
        second_comment_height=0;
        third_comment_height=0;


    }
    else if(comment_count==1)
    {
        second_comment_height=0;
        third_comment_height=0;

    }
    else if(comment_count==2)
    {

        third_comment_height=0;
    }
     float like_count=[user_post.like_count intValue];
    if(like_count<=0)
    {

        like_count_height=0;
    }
    float total_height=tv_view_height+like_count_height+first_comment_height+second_comment_height+third_comment_height;
    NSLog(@"total heigh is %f'",total_height);
    return total_height;
}

Please tell which is the best way?

Upvotes: 6

Views: 12319

Answers (5)

Md. Reaz Murshed Khan
Md. Reaz Murshed Khan

Reputation: 139

You should declare an array for storing TableView cells in cellForRowAtIndexPath and you can use stored cells in heightForRowAtIndexPath. Lets Try using this.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *cellIdentifier = @"HomeCellID";

     HomeCell *cell = (HomeCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

     if (!cell) {
          cell = [[[HomeCell alloc] init] autorelease];
     }

     // Store table view cells in an array
     if (![tableViewCells containsObject:cell]) {
          [tableViewCells addObject:cell];
     }

     return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     if([tableViewCellsArray objectAtIndex:indexPath.row]) {
          HomeCell *cell = (HomeCell *)[tableViewCells objectAtIndex:indexPath.row];
          // Process your Code
     }

     return yourCalculatedCellHeight;
}

Upvotes: 2

ifau
ifau

Reputation: 2120

How to get cell in heightForRowAtIndexPath?

It's impossible, because when -heightForRowAtIndexPath is called, no cells are created yet. You need to understand how the UITableView works:

  1. UITableView asks it's datasource how many sections it will have

    -numberOfSectionsInTableView

    At this point there are no cells created.

  2. UITableView asks it's datasource how many rows each section will have

    -numberOfRowsInSection

    At this point there are no cells created.

  3. UITableView asks it's delegate height of each visible row, to know where cells will be located

    -heightForRowAtIndexPath

    At this point there are no cells created.

  4. UITableView asks it's datasource to give it a cell to display at given index path

    -cellForRowAtIndexPath

    At this point the cell is created.

The height of each cell you can calculate from data model. You don't need the cell – you already know the frame width that will contain a comment, you know it's content, you know it's font, you know linebreak mode, etc. So, you can calculate height. For example:

CGFloat commentsHeight = 0;
Post *user_post = [arr_post objectAtIndex:indexPath.row];

for (NSString *comment in user_post.comments)
{
    CGRect commentrect = [comment boundingRectWithSize:CGSizeMake(self.view.bounds.size.width - 18, FLT_MAX)
                                          options:(NSStringDrawingUsesLineFragmentOrigin)
                                        attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]}
                                          context:nil];
    commentsHeight += commentrect.size.height;
}

And you can calculate height of the other components of cell from its data model.

But now, in 2015, it's not the best way. You really would be better to read the tutorials, which showed @Zil, and do it with Autolayout.

Upvotes: 17

Gil Sand
Gil Sand

Reputation: 6036

You could create a new cell from scratch, simply by HomeCell *sexyCell = [[HomeCell alloc]init];

or dequeue one like you did in cellForRow (tableView.dequeueWithReuseIdentifier:).

Though I advise creating one from scratch and disposing it after (setting it to nil), because if you dequeue it there they'll go in queue and cause heavy memory leaks and end up with many cells for the same indexPath.

What you COULD do is the following :

  • Create a cell with alloc init
  • Fill it with the real data
  • use .layoutsubviews on its view
  • calculate it's size and apply it to your real cell

What you SHOULD do :

Use auto layout and add all the constraints that are necessary, all your labels will size dynamically. It takes about 3 or 4 hours to get the basics of Auto layout, and about a month of regular use to really get the hang of it with ease.

I strongly strongly strongly suggest you do NOT resize using the frame of objects, most labels and views will resize like they should without having to write any code if you use constraints properly.

Once you have done that, because you have cells of varying heights, is using the DynamicHeight property of the tableview and the slight adjustements that comes with it. You can find

A great tutorial here

The same updated tutorial for swift (more up to date but you'd need to translate)

This amazing StackOverflow answer which you MUST read

Upvotes: 0

Vatsal Raval
Vatsal Raval

Reputation: 313

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:indexpath.row inSection:0];

Custom Cell *cell = [tableview cellForRowAtIndexPath:indexPath];

By this , you will get each cell in your method

Upvotes: -3

dirtydanee
dirtydanee

Reputation: 6151

I would recommend you to take the height form a configuration collection on your viewController.

Something like this:

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

    CGFloat height;
    CellConfiguration * selectedCellConfiguration =[_cellConfigurations objectAtIndex:indexPath.row];

    switch (selectedCellConfiguration.type) {
        case TheTypeYouNeed:
          return TheValueYouNeed
        default:
            height = 44.0f;
            break;
    }

    return height;
}

Upvotes: 0

Related Questions