繁体   English   中英

奇怪的UITableView插入/删除行动画

[英]Weird UITableView insert/delete row animation

在动画(UITableViewRowAnimationTop)的UITableView中插入/删除UITableViewCell时,我看到了一个奇怪的效果。

当要插入的单元格比上面的单元格大得多时,就会发生动画故障。

这个视频显示了模拟器中的故障,黄色单元突然出现在它应该从顶部滑动的地方。

是视频中的Xcode项目。

Bellow是细胞插入/动画代码。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 2 + self.thirdCellVisible;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];
        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];
        }
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == self.thirdCellIndexPath.row)
    {
        return 100.0f;
    }

    return 44.0f;
}

你必须打电话

[tableView beginUpdates] 

[tableView endUpdates] 

调用插入/删除方法之前和之后如下:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 2 + self.thirdCellVisible;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [self.tableView beginUpdates];

            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];

            [self.tableView endUpdates];

        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [self.tableView beginUpdates];

            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];

            [self.tableView endUpdates];

        }
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == self.thirdCellIndexPath.row)
    {
        return 100.0f;
    }

    return 44.0f;
}

根据Apple的说法:

要为行和节的批量插入,删除和重新加载设置动画,请在连续调用beginUpdates和endUpdates定义的动画块中调用相应的方法。 如果不在此块中调用插入,删除和重新加载方法,则行和节索引可能无效。 可以嵌套对beginUpdates和endUpdates的调用; 所有索引都被视为只有外部更新块。

在块结束时 - 也就是说,在endUpdates返回之后 - 表视图查询其数据源并像往常一样委托行和段数据。 因此,应更新支持表视图的集合对象以反映新的或删除的行或节。

在分别调用insert / delete方法之前和之后,你必须调用[tableView beginUpdates][tableView endUpdates]

Apple在上述链接中提供了一个示例。

注意 :如果您的数组和表视图项不同步,则在没有开始/结束调用的情况下将引发异常。

建议 :首先尝试使用withRowAnimation:UITableViewRowAnimationAutomatic

以下是我的工作代码的视频链接: https//dl.dropboxusercontent.com/u/30316681/480.mov

以下是我的工作代码:

@interface ViewController ()

@property (nonatomic, readwrite) BOOL thirdCellVisible;
@property (nonatomic, strong) NSIndexPath *thirdCellIndexPath;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.thirdCellIndexPath = [NSIndexPath indexPathForRow:2 inSection:0];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 2 + self.thirdCellVisible;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == self.thirdCellIndexPath.row)
    {
        return 100.0f;
    }

    return 44.0f;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                         withRowAnimation:UITableViewRowAnimationTop];
        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                         withRowAnimation:UITableViewRowAnimationTop];
        }
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellId = @"id";

    UITableViewCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:cellId];

    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }

    NSString *cellTitle = [NSString stringWithFormat:@"Cell %ld", (long)indexPath.row];

    cell.textLabel.text = cellTitle;

    if(indexPath.row == 2)
        cell.backgroundColor = [UIColor yellowColor];

    else
        cell.backgroundColor = [UIColor clearColor];

    return cell;
}

@end

使用[tableView beginUpdates][tableView endUpdates]如下所示

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;

            [self.tableView beginUpdates];
            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];
             [self.tableView endUpdates];

        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;

            [self.tableView beginUpdates];
            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];
             [self.tableView endUpdates];

        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM