在UITableView中批量插入时,第一个单元格的insertRowAnimation不起作用

时间:2014-05-23 17:18:20

标签: ios uitableview nsmutablearray key-value-observing

您好我正在尝试为我的模型添加一个观察者,以通知UITableview模型中的任何更改。使用这种模式,我可以解耦模型和视图,我可以将UITableViewDataSource放在另一个类中。

直到现在一切正常。但问题是,当我在tableView中插入多个对象时,第一行插入动画不起作用。

它只发生在UITableViewRowAnimationTop上。我已经在真实设备上进行了测试。但没有希望!

有没有人知道如何解决这个问题?

这是代码:

 - (void)viewDidLoad
{
    [super viewDidLoad];
    Item *item = [Item new];
    item.name = @"Computer";

    Item *item2 = [Item new];
    item2.name = @"lapTop";
    item2.parent = item;

    Item *item3 = [Item new];
    item3.name = @"NoteBook";
    item3.parent = item;

    item.children = [NSSet setWithObjects:item2,item3, nil];

    self.Items = [NSMutableArray arrayWithObject:item];

    [self addObserver:self
           forKeyPath:@"items"
              options:0
              context:NULL];
}

#pragma mark - Table View Data Source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.Items.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Item *object =(Item *)[self.Items objectAtIndex: indexPath.row];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    NSLog(@"%@",object.name);

    if (object.parent != NULL) {
        cell.indentationLevel = 1;
        cell.indentationWidth = 25;
    }
    cell.textLabel.text = object.name;
    return  cell;
}

#pragma  mark - Table View Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *dic=[self.Items objectAtIndex:indexPath.row];
    if([dic valueForKey:@"children"])
    {
        NSArray *children=[dic valueForKey:@"children"];
        BOOL isTableExpanded=NO;

        for(Item *child in children )
        {
            NSInteger index=[self.Items indexOfObjectIdenticalTo:child];
            isTableExpanded=(index>0 && index!=NSIntegerMax);
            if(isTableExpanded) break;
        }

        if(isTableExpanded)
        {
            [self CollapseRows:children];
        }
        else
        {
            NSUInteger count=indexPath.row+1;
            NSMutableArray *arrCells=[NSMutableArray array];
            for(Item *subItem in children )
            {
                NSLog(@"%@",subItem.name);
                if (subItem.parent != NULL) {
                    [arrCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
                    [self insertObject:subItem inItemsAtIndex:count++];
                }
            }

            //[self.tableView insertRowsAtIndexPaths:arrCells withRowAnimation:UITableViewRowAnimationTop];

        }
    }
}

-(void)CollapseRows:(NSArray*)ar
{
    for(NSDictionary *dInner in ar )
    {
        NSUInteger indexToRemove=[self.Items indexOfObjectIdenticalTo:dInner];
        NSArray *arInner=[dInner valueForKey:@"children"];
        if(arInner && [arInner count]>0)
        {
            [self CollapseRows:arInner];
        }

        if([self.Items indexOfObjectIdenticalTo:dInner]!=NSNotFound)
        {
            [self removeObjectFromItemsAtIndex:[self.Items indexOfObjectIdenticalTo:dInner]];
            //          [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:
            //                                                        [NSIndexPath indexPathForRow:indexToRemove inSection:0]
            //                                                        ]
            //                                      withRowAnimation:UITableViewRowAnimationTop];
        }
    }
}

#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    NSIndexSet *indices = [change objectForKey:NSKeyValueChangeIndexesKey];
    if (indices == nil)
        return; // Nothing to do


    // Build index paths from index sets
    NSUInteger indexCount = [indices count];
    NSUInteger buffer[indexCount];
    [indices getIndexes:buffer maxCount:indexCount inIndexRange:nil];

    NSMutableArray *indexPathArray = [NSMutableArray array];
    for (int i = 0; i < indexCount; i++) {
        NSUInteger indexPathIndices[2];
        indexPathIndices[0] = 0;
        indexPathIndices[1] = buffer[i];
        NSIndexPath *newPath = [NSIndexPath indexPathWithIndexes:indexPathIndices length:2];
        [indexPathArray addObject:newPath];
    }

    NSNumber *kind = [change objectForKey:NSKeyValueChangeKindKey];
    if ([kind integerValue] == NSKeyValueChangeInsertion)  // Rows were added
        [self.tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop];

    else if ([kind integerValue] == NSKeyValueChangeRemoval)  // Rows were removed
        [self.tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop];

}

#pragma mark Array Accessors
- (NSUInteger)countOfItems
{
    return [self.Items count];
}

- (id)objectInItemsAtIndex:(NSUInteger)idx
{
    return [self.Items objectAtIndex:idx];
}

- (void)insertObject:(id)anObject inItemsAtIndex:(NSUInteger)idx
{
    //[self willChangeValueForKey:@"menus"];
    [self.Items insertObject:anObject atIndex:idx];
}

- (void)removeObjectFromItemsAtIndex:(NSUInteger)idx
{
    [self.Items removeObjectAtIndex:idx];
}

1 个答案:

答案 0 :(得分:0)

您可以尝试直接在cellForRowAtIndexPath的第一个单元格图层上添加动画。

animation  = [CATransition animation];
[animation setType:kCATransitionFade];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setFillMode:kCAFillModeBackwards];
[animation setDuration:.2];
[cell.view.layer addAnimation:animation forKey:@"cellAnimation"]

https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CATransition_class/Introduction/Introduction.html