UITableView 一次添加一个带有动画的行,并具有明显的延迟



>我正在尝试向表视图添加 10 行,但我不是重新加载数据,而是在 for 循环中使用 insertRowsAtIndesPaths,但不是一次添加一行,而是在最后添加所有 10 行。这是我的代码...

if([[[[[notification userInfo] objectForKey:@"cityevent"]objectForKey:@"events"]objectForKey:@"event"] isKindOfClass:[NSArray class]])
{
    [self.featuredEventTableView beginUpdates];
    for(NSDictionary *tempDict in [[[[notification userInfo] objectForKey:@"cityevent"]objectForKey:@"events"]objectForKey:@"event"])
    {
        ESEvent *event=[[ESEvent alloc]init];
        event.name=[tempDict objectForKey:@"name"];
        if([[tempDict objectForKey:@"image"]isKindOfClass:[NSNull class]] || [tempDict objectForKey:@"image"] ==nil)
            event.image=[UIImage imageNamed:@"category_default.png"];
        else
        {
            event.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[tempDict objectForKey:@"image"]]]];
        }
        [events addObject:event];        
        NSIndexPath *ip=[NSIndexPath indexPathForRow:([events count]-1) inSection:0];
        NSLog(@"row: %i section: %i",ip.row,ip.section);
        [self.featuredEventTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationRight];
        [self.featuredEventTableView endUpdates];
    }
}

有什么建议吗?

将开始更新调用移到insertRowsAtIndexPaths:调用之前。 看看这是否有帮助。 我很惊讶这完全有效,因为您多次调用结束更新但只启动一次。

实际上,这可能仍然如此之快,以至于您甚至没有注意到。 查看NSTimer或 GCD 的dispatch_after以错开更新。

在这种情况下,for 循环无关紧要 - 操作系统会累积所有动画操作并将它们一起提交。若要正确执行此操作,必须使用动画停止选择器并调用外部方法来添加下一个单元格,直到添加完所有单元格。

为什么你不使用reloadData ...我想这将帮助您确定要在UI上显示的内容。如果您使用 for 循环并将一个数据添加到实际数组中,最后如果您调用 reload,它会给你这种效果。

如果您想继续使用现有代码,请尝试在我猜[self.featuredEventTableView endUpdates];之后添加[NSThread sleepForTimeInterval:0.5];.我不在我的Mac上,所以无法测试它。这会暂停当前线程一段时间,因此它将提供该动画效果。

编辑 尝试下面的代码

if([[[[[notification userInfo] objectForKey:@"cityevent"]objectForKey:@"events"]objectForKey:@"event"] isKindOfClass:[NSArray class]])
        {
            for(NSDictionary *tempDict in [[[[notification userInfo] objectForKey:@"cityevent"]objectForKey:@"events"]objectForKey:@"event"])
            {
                ESEvent *event=[[ESEvent alloc]init];
                event.name=[tempDict objectForKey:@"name"];
                if([[tempDict objectForKey:@"image"]isKindOfClass:[NSNull class]] || [tempDict objectForKey:@"image"] ==nil)
                   event.image=[UIImage imageNamed:@"category_default.png"];
                else
                {
                    event.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[tempDict objectForKey:@"image"]]]];
                }
                [events addObject:event];

                NSIndexPath *ip=[NSIndexPath indexPathForRow:([events count]-1) inSection:0];
                NSLog(@"row: %i section: %i",ip.row,ip.section);
// If this don't work then add thread sleep code at here.
[self.featuredEventTableView beginUpdates];             
   [self.featuredEventTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationRight];
                [self.featuredEventTableView endUpdates];
            }

        }
没有

一个答案有效。我按如下方式使用了NSTimer...

 tableTimer=[NSTimer scheduledTimerWithTimeInterval:0.4f target:self selector:@selector(performTableUpdates:) userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:i],@"count", nil] repeats:YES];

-(void)performTableUpdates:(NSTimer*)timer
{
    NSLog(@"%i",i);
    NSIndexPath *ip=[NSIndexPath indexPathForRow:i inSection:0];
    [newArray addObject:[events objectAtIndex:i]];
    [self.featuredEventTableView beginUpdates];
    [self.featuredEventTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationLeft];
    [self.featuredEventTableView endUpdates];
    if(i<[events count])
    {
        if([events count]-i==1)
        {
            [tableTimer invalidate];
            i++;
        }
        else
            i++;
    }
}

最新更新