Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem updating UITableViewCells when rotating UITableView

I have a UILabel in a custom UITableViewCell that gets resized when the device is rotated. The text in this label needs to be recalculated after the rotation because I am cutting it down to size and appending some text at the end.

E.g. the datamodel has: "This is a run-on sentence that needs to stop."

In portrait mode it becomes "This is a run-on sent... more"

In landscape mode it becomes "This is a run-on sentence that... more"

From (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation I am able to access the visible UITableViewCells and update the descriptions.

The problem seems to be that there are UITableViewCells that are cached but I can't get to. When I scroll the UITableView after a rotation, one or two cells that are below the visible area after the rotation don't have the correct text in the label. So they haven't been rendered via (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath - but they weren't returned by [tableView visibleCells] (or via looping through all views returned via [tableView subViews]).

I've tried to access the "extra" cells via this method:

for (int index=max + 1; index < max + 3 && index < [cellTypes count]; index++) {
    NSIndexPath *updatedPath = [NSIndexPath indexPathForRow:index inSection:0];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:updatedPath];
    if (cell == nil) { continue; }
    [self updateCellForRotate:cell forRow:index];
}

(where max is the biggest row returned from visibleCells) but cell is always nil.

Is there anyway to flush the cache of UITableViewCells so that they don't get re-used? Or to access them so I can update them?

Thanks!

like image 982
Michael Kernahan Avatar asked Sep 08 '10 18:09

Michael Kernahan


1 Answers

Two things. First. In your didRotateFromInterfaceOrientation method you can simply reload the visible rows like so:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation) fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    NSLog(@"didRotateFromInterfaceOrientation:%d",fromInterfaceOrientation);
    [tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}

Then I would recommend you add either the interfaceOrientation number or simply the table width to the dequeue cell name that way the tableView knows that cells in one rotation are different from those in another. Like so:

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath withType:(NSString *)s_type
{
    UITableViewCell *cell = nil;
    // add width of table to the name so that rotations will change the cell dequeue names
    s_cell = [s_cell stringByAppendingString:[NSString stringWithFormat:@"%@%d",@"Width",(int)tv.bounds.size.width]];

    NSLog(@"%@",s_cell);
    cell = [tv dequeueReusableCellWithIdentifier:s_cell];
    if( cell == nil ) { 
        cell = [[[UITableViewCell alloc];
        initWithFrame:CGRectZero reuseIdentifier:s_cell] autorelease];
    }
}
like image 115
ragamufin Avatar answered Sep 17 '22 18:09

ragamufin