iOS7中TableView删除最后一行时动画出现问题

12

我在删除我的tableView中唯一一个section的最后一行时遇到了问题。其他行都正常工作,但如果我随时删除底部的行(不仅是当它是最后一个时),动画会非常奇怪和卡顿。它看起来就不对。我还注意到更改动画类型没有任何效果。动画总是让行向上滑动并消失。将其更改为UITableViewRowAnimationFade或其他也没有任何效果。

这是我的代码:

//For the edit barButtonItem in my storyboard
- (IBAction)editButtonPressed:(id)sender {
    //enter editing mode
    if ([self.editButton.title isEqualToString:@"Edit"]) {
        [self setEditing:YES animated:YES];
        self.editButton.title = @"Done";
    } else {
        [self setEditing:NO animated:YES];
        self.editButton.title = @"Edit";
    }
}

//Editing the tableView. The user can only delete rows, not add any
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleDelete;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //Handle the data source and backend first, then the tableView row
        PFRelation *hasFavorites = [self.currentUser relationforKey:@"hasFavorites"];
        [hasFavorites removeObject:[self.favorites objectAtIndex:indexPath.row]];

        [self.favorites removeObjectAtIndex:indexPath.row];

        //It is set to fade here, but it only ever does the top animation
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

        //save to the backend
        [self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
            if (!error) {

            } else {
                NSLog(@"%@ %@", error, error.userInfo);
            }
        }];
    }
}

我查看了所有可以找到的答案,但都没有成功。在我的tableviewnumberOfSections中返回1,因为我只想要一个部分,而且我应该可以在一个部分中有0行,所以我认为这不是问题所在。


1
在你抓狂之前,你应该尝试使用一些本地应用程序(Notes.app是一个不错的选择)来重现这个问题。如果你有一个比屏幕高度小的表格,并且删除了最后一行,则该行会停滞一下,然后被删除。没有动画效果。我猜测这是操作系统本身的一个bug。 - mikekavouras
你正在设备上进行测试,对吗? - Guy Kogus
@GuyKogus 是的,在设备和模拟器上都有相同的行为。 - Stonep123
1
@mikekavouras,有趣。时钟应用程序确实表现出相同的行为。这是操作系统本身的一个错误。那很糟糕。 - Stonep123
4个回答

19

这是ios7的一个错误。表格行动画出现了问题!我的解决方法是在tableViewRowAnimation之前淡出单元格。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // hide cell, because animations are broken on ios7
    double iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (iosVersion >= 7.0 && iosVersion <= 8.0) {
        [tableView cellForRowAtIndexPath:indexPath].alpha = 0.0;
    }

    [tableView deleteRowsAtIndexPaths:@[indexPath]
                     withRowAnimation:UITableViewRowAnimationMiddle];
}

2
这个 bug 在 iOS 8 上似乎已经修复了,所以也许值得添加 "< 8.0" 的检查。 - Zmey

3

这里有一个我发现非常有效的解决方案,它基于jaydee3的答案构建:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{ 
     if (editingStyle == UITableViewCellEditingStyleDelete) {
          // hide cell, because animations are broken on ios7
          double iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];

          if (iosVersion >= 7.0 && iosVersion <= 8.0) {
              // Animating the cell's alpha change gives it a smooth transition
              // Durations > .17 show the glitch on iPad, phone looks nice up to 0.3
              [UIView animateWithDuration:0.17 animations:^(void) {
                  [tableView cellForRowAtIndexPath:indexPath].alpha = 0.0;
              }];
          }
          NSArray *deleteIndexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];

          // UITableViewRowAnimationFade looks nice with the animation imho
          [tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
     }
}

2

我也遇到了同样的Bug,只需将UITableViewRowAnimationMiddle的动画类型更改一下,就解决了所有问题。


UITableViewRowAnimationMiddle 对于每一行都有效,但它的效果与 UITableViewRowAnimationFade 不同,所以可能不是你想要的。 - Gobe

0

我对这个痛苦问题的解决方案 :)

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [UIView animateWithDuration:0.25f
                     animations:^{

                         UIScrollView *internalScrollView = (UIScrollView*)cell.contentView.superview;
                         if([internalScrollView isKindOfClass:[UIScrollView class]]){

                             [internalScrollView setContentOffset:CGPointZero animated:YES];
                         }

                         cell.center = CGPointMake(cell.center.x - cell.bounds.size.width, cell.center.y);

                     } completion:^(BOOL finished) {

                         [self.rowModels removeObjectAtIndex:indexPath.row];

                         [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
                     }];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接