尝试从UITableView中删除行和部分时收到错误。这是我的情景:
我有一个包含2个部分的UITableView。根据我在数据源模型中设置的标志,每个部分都有一行显示和隐藏。让我们说模型更改,我需要添加一个部分,现在删除另一部分中的可见行。所以我使用beginUpdates和endUpdates并包含所有状态更改。以下是如果我有以下数据会发生什么的具体示例:
旧州:
项目A)第0节 - 行= 0
项目B)第1节 - 行= 1
新州:
项目C)第0节 - 行= 0
项目B)第1节 - 行= 0
项目A)第2节 - 行= 0
正如您所看到的,我需要重新排序tableview(使用动画),添加新部分,并隐藏第1部分第1行。我在单个BeginUpdates / EndUpdates中执行所有这些增量。我先做部分,然后是行。我得到的错误如下:
NSRangeException', reason: '*** -[NSMutableIndexSet addIndexesInRange:]: Range {2147483647, 1} exceeds maximum index value of NSNotFound - 1'
我能够成功执行重新排序和部分添加/删除。当我尝试删除带有插入部分的行(带有重新排序)时,我遇到了一个问题。以下是模型更改后的一些数据输出日志,我正在尝试计算索引路径和索引集。
2012-02-27 07:33:13.565 XXX[1003:707] Setting new datasource state for cart
2012-02-27 07:33:13.571 XXX[1003:707] Adding section [0] to table
2012-02-27 07:33:13.574 XXX[1003:707] Moving section [0] to section [1]
2012-02-27 07:33:13.578 XXX[1003:707] Moving section [1] to section [2]
2012-02-27 07:33:13.581 XXX[1003:707] Removing indexPath for row [0] in section [0]
以下是计算更新,重新排序和删除的实际代码。
ShoppingCart *cart = [[SessionState sharedSession] activeCart];
// step 1) build the new array of items to set in current state
NSMutableArray *cartNewLineItemSections = [[NSMutableArray alloc] init];
// sections to remove and add to the current cart's state
NSMutableArray *indexSetsToAdd = [[NSMutableArray alloc] init];
NSMutableArray *originalSectionsToMove = [[NSMutableArray alloc] init];
NSMutableArray *changedSectionsToMove = [[NSMutableArray alloc] init];
// used in the loop to determine where the item is at currently if it exists
NSInteger currentOldOrderLineItemSectionIndex = -1;
for (NSInteger currentNewOrderLineItemIndex = 0; currentNewOrderLineItemIndex < [[[cart order] lineItems] count];
++currentNewOrderLineItemIndex) {
OrderLineItem *currentNewOrderLineItem = [[[cart order] lineItems] objectAtIndex:currentNewOrderLineItemIndex];
// currentNewOrderLineItemIndex corresponds to the section number
// create the new section info
CartLineItemSectionInfo *cartNewLineItemSection = [[CartLineItemSectionInfo alloc] init];
[cartNewLineItemSection setOpen:NO]; // defaults to NO
[cartNewLineItemSection setLineItem:currentNewOrderLineItem];
[cartNewLineItemSections addObject:cartNewLineItemSection];
// find the location of the current state
currentOldOrderLineItemSectionIndex = [cartLineItemSections indexOfObject:cartNewLineItemSection];
// no longer need the actual section since it has been added
[cartNewLineItemSection release], cartNewLineItemSection = nil;
// the new line item exists in old state
if (currentOldOrderLineItemSectionIndex != NSNotFound) {
// already in the same spot, do not worry about it
if (currentOldOrderLineItemSectionIndex == currentNewOrderLineItemIndex) {
continue;
}
[originalSectionsToMove addObject:[NSNumber numberWithInt:currentOldOrderLineItemSectionIndex]];
[changedSectionsToMove addObject:[NSNumber numberWithInt:currentNewOrderLineItemIndex]];
continue;
}
// the new line items are going to be added
[indexSetsToAdd addObject:[NSIndexSet indexSetWithIndex:currentNewOrderLineItemIndex]];
}
// find the deletions (for rows and sections)
NSMutableArray *indexSetsToRemove = [[NSMutableArray alloc] init];
NSMutableArray *rowPathsToRemove = [[NSMutableArray alloc] init];
for (NSInteger currentOldLineItemSectionIndex = 0; currentOldLineItemSectionIndex < [cartLineItemSections count];
++currentOldLineItemSectionIndex) {
CartLineItemSectionInfo *currentOldLineItemSection = [cartLineItemSections objectAtIndex:currentOldLineItemSectionIndex];
// sections must be deleted separately from the rows
if (![cartNewLineItemSections containsObject:currentOldLineItemSection]) {
[indexSetsToRemove addObject:[NSIndexSet indexSetWithIndex:currentOldLineItemSectionIndex]];
}
else if ([currentOldLineItemSection open]) {
// change the new one to YES to see what happens?
CartLineItemSectionInfo *sectionInfo = [cartNewLineItemSections objectAtIndex:[cartNewLineItemSections indexOfObject:currentOldLineItemSection]];
//[sectionInfo setOpen:YES]; // workaround
[rowPathsToRemove addObject:[NSIndexPath indexPathForRow:0 inSection:currentOldLineItemSectionIndex]];
}
}
// set the old state to the new state so that the UITableView can calculate state correctly
openSectionIndex = NSNotFound;
[cartLineItemSections release], cartLineItemSections = nil;
//NSLog(@"Setting new datasource state for cart");
cartLineItemSections = cartNewLineItemSections;
// animate table updates if there are any
if ([indexSetsToAdd count] > 0 || [indexSetsToRemove count] > 0 || [originalSectionsToMove count] > 0) {
[self.cartTableView beginUpdates];
// section additions
for (NSIndexSet *currentIndexSetToAdd in indexSetsToAdd) {
//NSLog(@"Adding section [%d] to table", [currentIndexSetToAdd firstIndex]);
[[self cartTableView] insertSections:currentIndexSetToAdd withRowAnimation:UITableViewRowAnimationRight];
}
// section moves
for (NSInteger currentIndexToMove = 0; currentIndexToMove < [originalSectionsToMove count]; ++currentIndexToMove) {
NSNumber *oldSection = [originalSectionsToMove objectAtIndex:currentIndexToMove];
NSNumber *changedSection = [changedSectionsToMove objectAtIndex:currentIndexToMove];
//NSLog(@"Moving section [%d] to section [%d]", [oldSection intValue], [changedSection intValue]);
[self.cartTableView moveSection:[oldSection intValue] toSection:[changedSection intValue]];
}
// section deletions
for (NSIndexSet *currentIndexSetToRemove in indexSetsToRemove) {
[self.cartTableView deleteSections:currentIndexSetToRemove withRowAnimation:UITableViewRowAnimationRight];
}
// row deletions
if ([rowPathsToRemove count] > 0) {
NSIndexPath *path = [rowPathsToRemove objectAtIndex:0];
NSLog(@"Removing indexPath for row [%d] in section [%d]", [path row], [path section]);
[self.cartTableView deleteRowsAtIndexPaths:rowPathsToRemove withRowAnimation:UITableViewRowAnimationTop];
}
[self.cartTableView endUpdates];
}
// release arrays
[indexSetsToAdd release], indexSetsToAdd = nil;
[indexSetsToRemove release], indexSetsToRemove = nil;
[originalSectionsToMove release], originalSectionsToMove = nil;
[changedSectionsToMove release], changedSectionsToMove = nil;
[rowPathsToRemove release], rowPathsToRemove = nil;
非常感谢任何帮助。谢谢!