UITableView Удаление строк и разделов - PullRequest
1 голос
/ 27 февраля 2012

Я получаю сообщение об ошибке при попытке удалить строку и раздел из 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;

Любая помощь очень ценится. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...