I am trying to resize the height of a UITableViewCell depending on what text is being displayed. I want the text to be fully shown.
I create a cell with specific TEXT_CELL label, in cellForRowAtIndexPath
if ([rowType isEqualToString:kTextCell] ) {
cell = [[[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
// Create a text view;
UITextView *newText = [[UITextView alloc] initWithFrame:CGRectZero];
newText.backgroundColor = [UIColor blueColor];
newText.tag = kNotesTag;
newText.editable = NO;
newText.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:newText];
[newText release];
}
And when I display the cell, I figure out the size required to show all the text using sizeOfFont function. Then I set that size as a variable, which is used in the heightOfCell function.
UITextView *notes = (UITextView*) [cell viewWithTag:kNotesTag];
if (notes != nil) {
notes.text = [self.managedObject dispalyValueForKeyPath:rowKey];
// resize it to the right height
CGRect contentFrame = cell.contentView.frame;
CGSize textSize = [notes.text sizeWithFont:[UIFont systemFontOfSize:[UIFont systemFontSize]]
constrainedToSize:CGSizeMake(contentFrame.size.width, CGFLOAT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
CGFloat newHeight = textSize.height + (CELL_CONTENT_MARGIN*2); //some space at the bottom
CGFloat textHeight = self.storedTextHeight;
if (textHeight != newHeight) {
[notes setFrame:CGRectMake(contentFrame.origin.x,
CELL_CONTENT_MARGIN+contentFrame.origin.y,
contentFrame.size.width, newHeight)];
self.storedTextHeight = newHeight;
// we reset the height fo the row, so reload it
[tView beginUpdates];
[tView endUpdates];
}
The calculation works as expected, and the heightForRow is called, and the cell height is updated. However, I always get SIGABT at the [tView endUpdates] line.
The error message is below. I googled a bunch, but not clear why this is the case. Not creating or adding cells.
* Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).’
Thanks for any insight on this.
Your crash report indicates the problem might not be stemming from your resizing strategy. It says that the number of rows is changing, but you aren’t changing the number of rows yourself. This is happening because of the way you reload your table.
To reload your table view, you should just call [tView reloadData] instead of
-beginUpdatesand-endUpdates.If you use
-beginUpdatesand-endUpdates, the table view will think you are making changes to the table manually, i.e. with-deleteRowsAtIndexPaths:withRowAnimation:and the lot. If you aren’t doing that (if you aren’t actually doing any updates yourself, which you aren’t), you should just be calling-reloadData. If you want to use-beginUpdatesand-endUpdates, then between the two calls you can insert:between the call to
-beginUpdatesand-endUpdates.Edit:
To help the performance of
-reloadData, you need to make sure you aren’t doing a lot of heavy lifting in-cellForRowAtIndexPath:, and also that you are reusing cells. There are lots of articles on the internet about table view performance:How expensive is UITableView's reloadData?
reloadData in tableView makes performance slow
Discussion here