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 同时滚动使滚动跳转