endUpdates 后的 UITableView 部分页脚视图位置

Posted

技术标签:

【中文标题】endUpdates 后的 UITableView 部分页脚视图位置【英文标题】:UITableView section footer view position after endUpdates 【发布时间】:2014-10-07 16:12:14 【问题描述】:

ios8 上,我使用的是核心数据表视图控制器,在删除行后,我的部分页脚视图突然一直下降到 UITableView 的底部。当我滚动表格视图时,页脚视图会回到它的位置。如何解决这个问题以及为什么会发生这种情况?

这是代码以防万一。

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
       
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    
        switch(type)
        
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeDelete:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
                break;

            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        
    


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

    if (self.beganUpdates)
    
       [self.tableView endUpdates];
    

【问题讨论】:

查看这篇文章***.com/questions/5740518/… 我针对这个问题提交了Radar。如果你想解决这个问题,我建议你们都这样做。骗子很有说服力。 【参考方案1】:

这是 iOS 8 的动画更改。您必须将 tableview 样式更改为“grouped”,以防止节页脚移动到 uitableview 的 bootom

【讨论】:

谢谢,这个解决方案对我有用。您有记录此内容的链接吗? 这个解决方案听起来更像是一种 hack,而不是解决问题的正确方法。【参考方案2】:

我刚刚遇到了同样的问题。当我使用 insertRowsAtIndexPaths.. 时,页脚位于底部。还注意到,如果您在表格视图上调用 reloadData 它将解决问题,所以我这样做了:

[CATransaction begin];
[CATransaction setCompletionBlock: ^
    // Code to be executed upon completion
    [tableView reloadData];
];

[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationLeft];
[CATransaction commit]; 

它所做的只是在插入动画完成时重新加载表格... 这不是一个真正的解决方案,更像是避免问题,但它隐藏了问题,直到有人解释它为什么会发生以及如何解决它......

【讨论】:

是的,你也可以这样做来避免这种情况(比重新加载数据更好,但它也很俗气): [self.tableView setContentOffset:CGPointMake(self.tableView.contentOffset.x, self. tableView.contentOffset.y-1)];【参考方案3】:

我遇到了同样的问题,并花了很多精力试图解决它。现在,终于!

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

    if (editingStyle == UITableViewCellEditingStyleDelete) 

        NATask *task = sections[indexPath.section][indexPath.row];
        [sections[indexPath.section] removeObjectAtIndex:indexPath.row];
        [appDelegate.managedObjectContext deleteObject:task];

        [CATransaction begin];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

        UIView *footerView = [tableView footerViewForSection:indexPath.section];
        CABasicAnimation *animation = [[footerView.layer animationForKey:@"position"] mutableCopy];
        CGPoint fromValue = [(NSValue *)animation.fromValue CGPointValue];
        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, fromValue.y - 44)];
        [footerView.layer removeAnimationForKey:@"position"];
        [footerView.layer addAnimation:animation forKey:@"position"];
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, .4 * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
            [tableView reloadData];
        );

        [CATransaction commit];
    

当然,这不是最理想的解决方案,但它确实有效!我已经为这个问题苦苦挣扎了将近两个星期,我希望至少对某人有用。

【讨论】:

【参考方案4】:

我遇到了同样的问题。到目前为止,没有一个答案能准确地告诉我我在寻找什么。将表格视图设置为“分组”不是我想要的行为,其他解决方案仍然导致页脚短暂位于表格视图的底部,直到调用 reloadData,他们突然将其重新定位到正确的位置。

以下是我的解决方案,可以将其平滑地动画到应有的位置。

NSIndexPath* iPath = [NSIndexPath indexPathForRow:_lineItemArray.count-1 inSection:0];

// Calculate the Y position of the bottom of the footer within the table view frame.
CGFloat footerBaseY = (_footer.y + _footer.height) - _sTableView.contentOffset.y;
// Calculate the Y position of the bottom taking into account the bottom content inset.
CGFloat tableViewContentBottomY = _sTableView.height - _sTableView.contentInset.bottom;

if (footerBaseY < tableViewContentBottomY) 
    [_sTableView insertRowsAtIndexPaths:@[iPath] withRowAnimation:UITableViewRowAnimationBottom];
    [UIView animateWithDuration:0.3
                     animations:^
                         CGFloat y = _lineItemArray.count * [_sTableView rectForRowAtIndexPath:iPath].size.height;
                         CGFloat newBaseY = (y + _footer.height) - _sTableView.contentOffset.y;

                         if (newBaseY < tableViewContentBottomY) 
                             _footer.y = y;
                          else 
                             // The footer is within a cell's height away from the bottom.  Subtract the diff from the new y.
                             _footer.y = y - (newBaseY - tableViewContentBottomY);
                         
                      completion:^(BOOL finished) 
                         // This ensures that the bottom row animates up if the footer was within a cell's height away from the bottom.
                         [_sTableView scrollToRowAtIndexPath:iPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
                     ];
 else 
    // The footer was already at the bottom of the vew so I'm animating the added row up.
    [_sTableView insertRowsAtIndexPaths:@[iPath] withRowAnimation:UITableViewRowAnimationBottom];
    [_sTableView scrollToRowAtIndexPath:iPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

【讨论】:

【参考方案5】:

我仍然需要部分页眉和页脚视图保持粘性。因此,我没有将 tableview 样式更改为 Grouped,而是在删除行后简单地做了一个 reloadSection...

【讨论】:

以上是关于endUpdates 后的 UITableView 部分页脚视图位置的主要内容,如果未能解决你的问题,请参考以下文章

UITableView - BeginUpdates/EndUpdates 动画设置

UITableView beginUpdates/endUpdates 回调

执行“beginUpdates”“endUpdates”时 UITableView 页脚视图的动画问题

UITableView beginUpdates/endUpdates 同时滚动使滚动跳转

beginUpdates和endUpdates 实现UITableView的动画块

UITableView endUpdates 在 vi​​ewDidLoad 中调用时崩溃