【问题标题】:UITableView section footer view position after endUpdatesendUpdates 后的 UITableView 部分页脚视图位置
【发布时间】: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];
    }
}

【问题讨论】:

标签: ios objective-c uitableview ios8


【解决方案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...

      【讨论】:

        猜你喜欢
        • 2014-12-02
        • 2011-12-21
        • 2010-12-26
        • 2011-09-17
        • 1970-01-01
        • 2017-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多