UITableView删除行和节

时间:2012-02-27 14:42:39

标签: objective-c ios cocoa-touch uitableview

尝试从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;

非常感谢任何帮助。谢谢!

0 个答案:

没有答案