3

I am building a application without the IB and I am writing everything from scratch. I have a custom UITableViewCell and when I try to calculate the height, it behaves like there are no subviews. I could find a lot of discussion about dynamically setting the height, but nothing really about how to calculate it, based on the subviews and how and where to set the constraints. What I did is setting constraints for my first component - UIImageView and add them the contenView of my cell. What I get is 0.

I will appreciate any input on that or at least direction!

heightForRowAtIndexPath:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell* cell = [[UITableViewCell alloc]init];
    cell.imageView.image = [UIImage imageNamed:@"avatar"];

    cell.imageView.translatesAutoresizingMaskIntoConstraints=NO;

    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[image]" options:0 metrics:nil views:@{ @"image": cell.imageView }];

    [cell.contentView addConstraints:constraints];

    NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[image]" options:0 metrics:nil views:@{ @"image": cell.imageView}];

    [cell.contentView addConstraints:constraints2];

    [ NSLayoutConstraint constraintWithItem:cell.imageView attribute: NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual toItem:cell.imageView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0f];

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

    NSLog(@"%f",height);

    return height;

}
Neli Chakarova
  • 660
  • 1
  • 5
  • 18

2 Answers2

0

My solution for this kind of problem is UITableViewAutomaticDimension. You just return this in heightForRowAtIndexPath method. You will have to set tableView.estimatedRowHeight to some value that is close to what you will get.

For instance, if you have 5 cells with height [100,200,250,270,300] you can set estimatedRowHeight to 220 (or something similar).

You can take a look at first answer at Using Auto Layout in UITableView for dynamic cell layouts & variable row heights as well.

Community
  • 1
  • 1
Miknash
  • 7,888
  • 3
  • 34
  • 46
  • What I am getting is -1. – Neli Chakarova Jul 14 '15 at 11:19
  • Because it is calculated later on, you use this value to let uitableview know that it will caluclate the height. Do you get UI right? – Miknash Jul 14 '15 at 11:34
  • I guess not... I get a new warning,though: Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead. Shouldn't the content view be set automatically to a value when a set the constrains of the UIImageView ? – Neli Chakarova Jul 14 '15 at 11:40
  • try to implement estimatedHeightForRowAtIndexPath, that should get rid of the warning. I am using this kind of approach in few projects, and it renders ui right, with fullfilling all the constraints. – Miknash Jul 14 '15 at 11:45
  • Not working either and I am getting the same warning. What I am thinking is that I am missing something when building the custom cell, but I don't know yet what. – Neli Chakarova Jul 14 '15 at 11:49
  • Ah, you are right, you are accessing default elements for uitableviewcell, what you should do is create new class to subclass UITableViewCell, create xib and create elements there. I am not 100% sure but I think that you cannot modify position of the UITableviewCell default elements ( image, title, details title, accessories) – Miknash Jul 14 '15 at 11:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/83200/discussion-between-nickcatib-and-neli-chakarova). – Miknash Jul 14 '15 at 11:54
  • What I did and what you suggested were both right. The only thing I was missing in mine was that I had only the constraint to one of the borders of the superview and I needed both of them. – Neli Chakarova Jul 25 '15 at 11:56
0

I'm not sure that will work, or that it is correct but try this way

static NSInteger someCell = 1;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [UITableViewCell new];
    cell.tag = someCell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.tag == someCell) return 100.;
    return 30.;
}
Shklyar
  • 140
  • 1
  • 12