RowAnimation 对于不同高度的单元格看起来很奇怪

发布于 2024-10-01 06:17:08 字数 2458 浏览 0 评论 0原文

我在 UITableView 上动画删除和插入时遇到问题。事实是,我现在有不同的单元格高度,有些是 44.0,有些是 135.0。我有 uitableviewstyle 与不同的部分分组。每个部分的第一行是分组行。单击后,我将删除该部分中除分组行之外的所有行。但是当对 135px 高度的单元格进行动画处理 (UITableViewRowAnimationTop) 时,该动画看起来很奇怪。我尝试将 self.tableview.cellheight 设置为 135 并注释掉 tableView:cellHeightForIndexPath-Method 。而且动画效果很好。或者我在 tableView:cellHeightForIndexPath-Method 中将每个单元格高度设置为 135。

看起来动画过程会检查各部分中第一行的高度,并采用该单元格的高度来为所有后续单元格设置动画。

有人有主意吗?


- (void) showhideGroup:(int)group
{   
    NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
    
    MCGroup *handleGroup = [groups objectAtIndex:group];
    NSMutableArray *groupRows = [visibleGroupData objectForKey:handleGroup.title];
    
    [self.tableView beginUpdates];
    
    if (!handleGroup.hidden) {
        int row = 0;
        for(MobileFieldMapping *field in groupRows)
        {
            if (![field.datatype matchesInsensitive:GROUPING_CELL]) 
            {
                NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:group];
                [indexPaths addObject:path];
            }
            row++;
        }
        
        row = 0;
        for(NSIndexPath *index in indexPaths)
        {
            [groupRows removeObjectAtIndex:index.row-row];
            row++;
        }
        [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
        handleGroup.hidden=YES;
    }
    else 
    {
        NSMutableArray *allGroupRows = [groupData objectForKey:handleGroup.title];
        
        int row = 0;
        for (MobileFieldMapping *field in allGroupRows) 
        {
            if (![groupRows containsObject:field]) 
            {
                NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:group];
                [indexPaths addObject:path];
                [groupRows insertObject:field atIndex:row];
            }
            row++;
        }
        
        [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
        handleGroup.hidden=NO;
    }
    [self.tableView endUpdates];


    [indexPaths release];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    
    if ([cell isKindOfClass:[FormCell class]]) 
    {
        return [(FormCell*)cell height];
    }
    
    return 44.0;
}

I have a problem with animating deletes and inserts on a UITableView. The Fact ist, that I have different cell heights, some 44.0 some 135.0 now. I have uitableviewstylegrouped with different sections. The first row of each sections is a grouping row. On click I remove all rows of this section except the grouping row. But that animation looks weird, when animating (UITableViewRowAnimationTop) the 135px height cell. I tried to set self.tableview.cellheight to 135 and commented out the tableView:cellHeightForIndexPath-Method. And the Animation works fine. Or I set every cellheight to 135 in tableView:cellHeightForIndexPath-Method.

It looks like the animation process checks the height of the first row in the sections an takes that height of the cell for all following cells to animate.

Somebody has an idea?


- (void) showhideGroup:(int)group
{   
    NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
    
    MCGroup *handleGroup = [groups objectAtIndex:group];
    NSMutableArray *groupRows = [visibleGroupData objectForKey:handleGroup.title];
    
    [self.tableView beginUpdates];
    
    if (!handleGroup.hidden) {
        int row = 0;
        for(MobileFieldMapping *field in groupRows)
        {
            if (![field.datatype matchesInsensitive:GROUPING_CELL]) 
            {
                NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:group];
                [indexPaths addObject:path];
            }
            row++;
        }
        
        row = 0;
        for(NSIndexPath *index in indexPaths)
        {
            [groupRows removeObjectAtIndex:index.row-row];
            row++;
        }
        [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
        handleGroup.hidden=YES;
    }
    else 
    {
        NSMutableArray *allGroupRows = [groupData objectForKey:handleGroup.title];
        
        int row = 0;
        for (MobileFieldMapping *field in allGroupRows) 
        {
            if (![groupRows containsObject:field]) 
            {
                NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:group];
                [indexPaths addObject:path];
                [groupRows insertObject:field atIndex:row];
            }
            row++;
        }
        
        [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
        handleGroup.hidden=NO;
    }
    [self.tableView endUpdates];


    [indexPaths release];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    
    if ([cell isKindOfClass:[FormCell class]]) 
    {
        return [(FormCell*)cell height];
    }
    
    return 44.0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风流物 2024-10-08 06:17:08

我也有同样的问题。
我的解决方法是使用淡入淡出部分动画:

[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];

而不是元素动画:

[tableView deleteRowsAtIndexPaths:tmpArray withRowAnimation:UITableViewRowAnimationTop];

这看起来更平滑。

I had the same problem.
My workaround is to use fade section animation:

[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];

Instead of one for elements:

[tableView deleteRowsAtIndexPaths:tmpArray withRowAnimation:UITableViewRowAnimationTop];

This looks much smoother.

枯叶蝶 2024-10-08 06:17:08

一个仍然没有答案的旧问题。我想你很久以前就明白了,但这是我的第一个想法。 (我记得自己尝试做这样的事情。)

UITableView 调用 heightForRowAtIndexPath: 时,这是因为表格正在尝试准备单元格,所以你可以' t 使用单元格返回高度。这可能会导致调用中的无限回归,或者它可能会检测到这一点并放弃或抛出异常,让您独自承担责任。

您必须在不使用单元本身的情况下计算单元高度。

至于单元格高度假设,请尝试对单个单元格调用插入/删除,而不是一次调用一次来完成所有操作。在您调用 endUpdates 后,UITableView 仍会将它们批处理以用于动画。

An old one that is still unanswered. I assume you figured it out a long time ago, but here is my first thought. (I recall trying to do something like this myself.)

When the UITableView calls heightForRowAtIndexPath:, it will be because the table is trying to prepare the cell, so you can't use the cell to return the height. This may cause an infinite regression in calls or it may detect this and just give up or throw an exception and leave you holding the bag.

You must calculate the cell height without using the cell itself.

As for the cell height assumption, try calling insert/delete for individual cells rather than a single call to do it all at once. The UITableView will still batch them up for the animation after you call endUpdates.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文