11

I have a UITableView with cells containing variable-height UILabels. I am able to calculate the minimum height the label needs to be using sizeWithFont:constrainedToSize:lineBreakMode:, which works fine when the table view is first loaded. When I rotate the table view the cells become wider (meaning there are fewer lines required to display the content). Is there any way I can have the height of the cells redetermined by the UITableView during the orientation change animation or immediately before or after? Thank you.

Peter Zich
  • 512
  • 3
  • 13
  • How do you get the size (width) used for sizeWithFont:constrainedToSize:lineBreakMode: ? I'm trying to make a variable-height cell that work for plain & grouped tableview style, but can't figure out how to get the width of the grouped tableview – flagg19 Jun 15 '12 at 14:09

2 Answers2

13

Your UITableViewController can implement the tableView:heightForRowAtIndexPath: method to specify the row height for a particular row, and it can look at the current orientation ([[UIDevice currentDevice] orientation]) to decide what height to return.

To make sure tableView:heightForRowAtIndexPath: gets called again when the orientation changes, you'll probably need to detect the orientation change as described in this question, and call [tableView reloadData].

Community
  • 1
  • 1
David Gelhar
  • 27,873
  • 3
  • 67
  • 84
  • I currently have `tableView:heightForRowAtIndexPath:` implemented, I didn't see it getting called on orientation change but it does get called on `reloadData` and I can detect the orientation change. If possible I'd like to have the height animate as the view rotates, but I'm not seeing that as a possibility. – Peter Zich Apr 27 '10 at 04:20
  • 3
    According to this question: http://stackoverflow.com/questions/460014/can-you-animate-a-height-change-on-a-uitableviewcell-when-selected you might be able to do the animation by using `beginUpdates`/`endUpdates` instead of `reloadData` – David Gelhar Apr 27 '10 at 11:17
  • 1
    That works perfectly, David, thank you. I put this code in `-didRotateFromInterfaceOrientation` and it works great. Right now it rotates and then resizes. I'm going to look for a better method to put this in and see if I can get it to resize as it rotates. – Peter Zich May 05 '10 at 23:54
12

To improve slightly on the answer above from @David and to answer the last comment about how to animate it smoothly during a rotation, use this method:

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

and of course the height delegate method:

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
        return 171.0f;
    } else {
        return 128.0f;
    }
}
bandejapaisa
  • 26,576
  • 13
  • 94
  • 112
  • Thanks! I was going insane! Any idea why statusBarOrientation works and orientation alone doesn't when you first initialize the app? Once running, and the orientation changes, both work fine. – Jan Aug 26 '13 at 09:37
  • UIDevice orientation and UIInterface orientation (from the statusBar) are not the same. UIDevice could be in UIDeviceOrientationFaceUp (ie your iPad sat flat on a table) - which doesn't tell you what the orientation of the interface is, which could be any of 4. – bandejapaisa Aug 27 '13 at 12:59