Я получаю сообщение об ошибке при попытке удалить строку и раздел из UITableView. Вот мой сценарий:
У меня есть UITableView с 2 разделами. В каждом разделе есть одна строка, которую я показываю и скрываю, основываясь на флаге, который я установил в модели источника данных. Допустим, модель меняется, и мне нужно добавить один раздел, а теперь удалить видимую строку в другом разделе. Поэтому я использую beginUpdates и endUpdates и включаю все изменения состояния. Вот конкретный пример того, что происходит, если у меня есть следующие данные:
Старое государство:
Элемент A) Раздел 0 - Строки = 0
Элемент B) Раздел 1 - Строки = 1
Новый штат:
Элемент C) Раздел 0 - Строки = 0
Элемент B) Раздел 1 - Строки = 0
Элемент A) Раздел 2 - Строки = 0
Итак, как вы можете видеть, мне нужно изменить порядок таблицы (с анимацией), добавить новый раздел и скрыть строку 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;
Любая помощь очень ценится. Спасибо!