Edit:
The solution for this answer is related to iOS7 sometimes returning NSIndexPath
and other times returning NSMutableIndexPath
. The issue wasn't really related to begin/endUpdates
, but hopefully the solution will help some others.
All - I'm running my app on iOS 7, and I'm running into problems with the beginUpdates
and endUpdates
methods for a UITableView
.
I have a tableview that needs to change the height of a cell when touched. Below is my code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// If our cell is selected, return double height
if([self cellIsSelected:indexPath]) {
return 117;
}
// Cell isn't selected so return single height
return 58;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
ChecklistItemCell *cell = (ChecklistItemCell *)[self.tableview cellForRowAtIndexPath:indexPath];
[cell.decreaseButton setHidden:NO];
[cell.increaseButton setHidden:NO];
// Toggle 'selected' state
BOOL isSelected = ![self cellIsSelected:indexPath];
DLog(@"%@", selectedIndexes);
DLog(@"is selected: %@", isSelected ? @"yes":@"no");
// Store cell 'selected' state keyed on indexPath
NSNumber *selectedIndex = @(isSelected);
selectedIndexes[indexPath] = selectedIndex;
[tableView beginUpdates];
[tableView endUpdates];
}
The beginUpdates
and endUpdates
methods are working pretty inconsistently. The didSelectRowAtIndexPath
method gets called correctly on each touch(I thought at first the UI was getting blocked), and the selectedIndexes
is storing alternating values correctly. The issue is, sometimes I touch a table cell and all the methods are called properly, but the cell height doesn't change. Anyone know what's going on?
There is a change in behavior in iOS7 where index paths are sometimes instances of NSIndexPath
and other times UIMutableIndexPath
. The problem is that isEqual
between these two classes is always going to return NO
. Thus, you cannot reliably use index paths as dictionary keys or in other scenarios that rely on isEqual
.
I can think of a couple of viable solutions:
Write a method that always returns an instance of NSIndexPath
and use it to generate keys:
- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath class] == [NSIndexPath class]) {
return indexPath;
}
return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}
Identify rows by the data, not the index path. For example, if your data model is an array of NSString
, use that string as the key into your selectedIndexes
map. If your data model is an array of NSManagedObjects
, use the objectID
, etc.
I'm successfully using both of these solutions in my code.
EDIT Modified solution (1) based on @rob's suggestion of returning NSIndexPaths
rather than NSStrings
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With