Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView with dynamic cell heights -- what do I need to do to fix scrolling down?

I am building a teensy tiny little Twitter client on the iPhone. Naturally, I'm displaying the tweets in a UITableView, and they are of course of varying lengths. I'm dynamically changing the height of the cell based on the text quite fine:

- (CGFloat)heightForTweetCellWithString:(NSString *)text {
  CGFloat height = Buffer + [text sizeWithFont:Font constrainedToSize:Size lineBreakMode:LineBreakMode].height;
  return MAX(height, MinHeight);
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  NSString *text = // get tweet text for this indexpath
    return [self heightForTweetCellWithString:text];
  }
}

I'm displaying the actual tweet cell using the algorithm in the PragProg book:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *CellIdentifier = @"TweetCell";
  TweetCell *cell = (TweetCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
    cell = [self createNewTweetCellFromNib];
  }
  cell.tweet.text = // tweet text
  // set other labels, etc
  return cell;
}

When I boot up, all the tweets visible display just fine. However, when I scroll down, the tweets below are quite mussed up -- it appears that once a cell has scrolled off the screen, the cell height for the one above it gets resized to be larger than it should be, and obscures part of the cell below it. When the cell reaches the top of the view, it resets itself and renders properly. Scrolling up presents no difficulties.

Here is a video that shows this in action: http://screencast.com/t/rqwD9tpdltd

I've tried quite a bit already: resizing the cell's frame on creation, using different identifiers for cells with different heights (i.e. [NSString stringWithFormat:@"Identifier%d", rowHeight]), changing properties in Interface Builder...

If there are additional code snippets I can post, please let me know. Thanks in advance for your help!

like image 756
Ian Terrell Avatar asked Mar 25 '09 02:03

Ian Terrell


People also ask

Is UITableView scrollable?

UITableView scrolls back because it's content size is equal to it's frame (or near to it). If you want to scroll it without returning you need add more cells: table view content size will be large then it's frame.

How can I tell if a tableView is scrolling?

Since a scrollView has a panGesture we can check the velocity of that gesture. If the tableView was programmatically scrolled the velocity in both x and y directions is 0.0. By checking this velocity we can determine if the user scrolled the tableView because the panGesture has a velocity.

How do you make a table dynamic cell height?

To get dynamic cell heights working properly, you need to create a custom table view cell and set it up with the right Auto Layout constraints.


1 Answers

Sigh. Turns out I didn't tweak all the properties just quite well enough. But at least I'm rid of that bug. :)

This behavior was fixed by being sure to check the "Clip Subviews" property of the UITableViewCell.

The behavior was caused by declaring my tweet text label to be of the maximum height necessary -- when the subviews of the table cell were not clipped, the label in the cell above would render overtop of the cell below. This was not visible on the first rendering of the screen due to the order that the SDK renders the cells -- downward -- and how it stacks each one above the other.

like image 105
Ian Terrell Avatar answered Sep 22 '22 06:09

Ian Terrell