防止 UITableView 超出单元格绑定视图在 insertRowsAtIndexPaths 上剪辑:

Posted

技术标签:

【中文标题】防止 UITableView 超出单元格绑定视图在 insertRowsAtIndexPaths 上剪辑:【英文标题】:Prevent UITableView out of cell bound views from clipping on insertRowsAtIndexPaths: 【发布时间】:2014-07-31 23:17:43 【问题描述】:

视频展示了在插入新单元格时,视图延伸到单元格区域之外的单元格如何被瞬间剪裁:

https://dl.dropboxusercontent.com/u/22105205/CellClipping.mov

这个简单项目清楚地显示了问题,可用于快速原型设计:

https://github.com/AndresCanella/iosInsertCellClippingExample.git

仅当表发生变异时才会发生这种剪裁。 细胞清晰。 细胞在不发生变异时正确显示。

可能是某种只使用单元格区域内的像素进行动画的优化?

一切都设置正确、稳定并且按预期工作,我们甚至没有在这个例子中使用特定的单元格数据:

[tableView beginUpdates];
self.cells++;
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
[tableView endUpdates];

更新:

来自 DTS 的回应:

恐怕在调用“insertRowsAtIndexPaths”时,无论您使用哪种“UITableViewRowAnimation”,您都无法直接影响插入动画的行为。单元格内容通常不会像那样重叠。 UITableView 在执行每个单元格的动画块时只是尊重单元格的边界(不是扩展或重叠的内容)。

我的评论:

DTS 告诉我,事情可以做很多次,我总能找到解决方法。所以现在我正在寻找解决方法。

Apple 错误报告 #17986466

【问题讨论】:

【参考方案1】:

在我看来,您不希望被剪裁的视图超出了单元格本身的范围。对我来说,这意味着这些应该是表格视图而不是单元格的子视图。

如果确实如此,您可能希望使用普通的 UIScrollView 而不是 UITableView,并为向下插入的视图下方的视图设置动画。

【讨论】:

是的,如描述的第一行所述。我将更新名称以包含此名称。问题是在这种情况下的解决方案。最终使用是一个单元格重的环境,UIScrollView 不是解决方案。【参考方案2】:

根据我的经验,如果您想避免奇怪的布局和动画故障,您应该尝试让单元格保持不清晰/透明的背景并设置为剪辑子视图。

在表格视图中设置单元格视图层次结构的方式以及制作动画的方式是 Apple 内部实现的,并且在未来的版本中可能会发生更改,恕不另行通知。


表格视图擅长显示大量行和重用视图,这些东西可能您的视图并没有真正使用。如果您想要的布局不需要多个可滚动内容的屏幕,那么您应该尝试创建自己的自定义基于UIScrollView 的视图或在众多开源库中搜索一个。您可以完全控制动画并添加自定义行为。

【讨论】:

是的,我很清楚这不是理想的用途,但我们的设计需要它。随着每个构建 iOS 越来越支持它。每次使用 reloadData 时,我们的重叠始终都能完美运行,只是这种特殊情况有问题。【参考方案3】:

我知道这是一个完整的 hack - 但它确实修复了剪辑。

对于精细动画 - 查看 PRTWeen。 https://github.com/jdp-global/MWDatePicker

我猜你考虑过在当前单元格和上一个单元格上切换 2 个透明背景图像(红色和绿色)(640px x100px)?它可以在插入时使用淡入淡出的动画来工作。

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


    self.cells++;
    [self.tb reloadData];

    [self performSelector:@selector(fancyAnimate:) withObject:indexPath afterDelay:0];



-(void)fancyAnimate:(NSIndexPath*)path
    NSIndexPath *idx = [NSIndexPath indexPathForRow:path.row inSection:path.section] ;

    UITableViewCell *cell = (UITableViewCell*)[self.tb cellForRowAtIndexPath:idx];
    CGRect frame = cell.frame;
    frame.origin.x = 320;
    cell.frame = frame;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    frame.origin.x = 0;
    cell.frame = frame;
    [UIView commitAnimations];



【讨论】:

时间结束,因提供解决方案尝试而获奖,但不是解决问题“在 insertRowsAtIndexPaths 上剪裁:”的解决方案。 insertRowsAtIndexPaths: 的用户是为了避免使用 reloadData。这对滚动和许多其他方面都有负面影响。 谢谢安德烈斯。注:我在我的设备 ios 7.0.4 上看到 - 剪辑每个单元格(不改变 tableview)。 7.1 很好,模拟器按预期工作。 确实如此。在 7.1 之前,您需要横向子单元格视图并设置不剪裁。所以这是固定的,这暗示苹果越来越多地支持重叠......我已经向苹果提交了一份错误报告。

以上是关于防止 UITableView 超出单元格绑定视图在 insertRowsAtIndexPaths 上剪辑:的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 选定的单元格在旋转到横向时超出当前视图

防止 UITableView 在自定义子视图处理触摸时滚动

删除 UITableView 中的最后一个单元格时索引超出范围

UITableView有单元格,但没有显示单元格

UITableView:停止自动滚动超出所选位置

UITableView 重复单元格如何防止呢?迅速