Reputation: 3970
I have developed a UITableView
with some cells that could have subcells.
Example:
My app allows users to move cells position but, when a table has got one or more cell with subcells, I collapse all of them in order to allow only move cells with the same identation (or in the same level)
If the table is pretty long, when I collapse cells with subelements, I use indexPath of that cell to remove the subelements from the table. My problem is that some of that cells are not in memory so I get a crash.
How can I detect that a cell is not being showed in order only remove the element from the dataSource?
This is my method to collapse/expand elements:
- (void)expandCollapseSubtasks:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:_taskTableView]; //when CGPoint = 0,0 not remove cells?
NSIndexPath *indexPath = [_taskTableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
Task *task = [_tasks objectAtIndex:indexPath.row];
TaskTitleCell *cell = (TaskTitleCell *)[_taskTableView cellForRowAtIndexPath:indexPath];
UILabel *subtasksNumberLabel = (UILabel *)[cell viewWithTag:107];
UIButton *subtasksButton = (UIButton *)[cell viewWithTag:108];
NSMutableArray *subtasksIndexPaths = [[NSMutableArray alloc] init];
NSNumber *hidden;
//Expand
if (!subtasksButton.selected){
hidden = @0;
subtasksNumberLabel.textColor = [UIColor colorWithRed:72.0/255.0 green:175.0/255.0 blue:237.0/255.0 alpha:1.0];
NSDictionary *subtasksAndIndexesDictionary = [task getSubtasksIndexesInTaskCollection:_tasks ofList:task.list];
NSIndexSet *indexes = [subtasksAndIndexesDictionary objectForKey:@"indexes"];
NSArray *subtasks = [subtasksAndIndexesDictionary objectForKey:@"subtasks"];
[_tasks insertObjects:subtasks atIndexes:indexes];
[indexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSIndexPath *subtaskIndexPath = [NSIndexPath indexPathForRow:idx inSection:0];
[subtasksIndexPaths addObject:subtaskIndexPath];
}];
[_taskTableView insertRowsAtIndexPaths:subtasksIndexPaths withRowAnimation:UITableViewRowAnimationTop];
//Collapse
}else{
hidden = @1;
subtasksNumberLabel.textColor = [UIColor whiteColor];
NSArray *subtasks = [task getSubtasks];
[_tasks removeObjectsInArray:subtasks];
for (int i=1;i<=subtasks.count; i++){
NSIndexPath *subtaskIndexPath = [NSIndexPath indexPathForRow:indexPath.row+i inSection:0];
[subtasksIndexPaths addObject:subtaskIndexPath];
}
[_taskTableView deleteRowsAtIndexPaths:subtasksIndexPaths withRowAnimation:UITableViewRowAnimationBottom];
}
subtasksButton.selected = !subtasksButton.selected;
task.hidesubtasks = hidden;
[[NSManagedObjectContext defaultContext] saveToPersistentStoreAndWait];
}
}
And the call
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
UITableViewCell *cell = [_taskTableView cellForRowAtIndexPath:indexPath];
UIButton *subtasksButton = (UIButton *)[cell viewWithTag:108];
[self expandCollapseSubtasks:subtasksButton];
Where idx
is the position of the element in the dataSource
Upvotes: 0
Views: 52
Reputation: 25459
You can get array of NSIndexPath for all visible cells:
NSArray *array = [self.tableView indexPathsForVisibleRows];
You can also get array of cells itself instead of NSIndexPath:
[tableView visibleCells]
That what you need to find out the invisible cells.
Upvotes: 1