0

我有一个自定义 UITableViewCell 来实现使用 UIAttachmentBehavior 和 UIPanGestureRecognizer 水平滑动。这是 UITableViewCell 子类中的相关部分:

- (void)panDidChange:(UIPanGestureRecognizer *)gesture {
CGPoint location = [gesture locationInView:[self tableView]];
location.y = CGRectGetMidY(self.frame);
switch (gesture.state) {
    case UIGestureRecognizerStateBegan: {
        self.panAttachment = [[UIAttachmentBehavior alloc] initWithItem:self attachedToAnchor:location];
        [self.animator addBehavior:self.panAttachment];

        break;
    }

然后,当 UIGestureRecognizerStateChanged 时,我只是将 self.panAttachment.anchorPoint 设置为位置。

现在,这从启动开始就可以正常工作,但是一旦我将一个单元格添加到 tableView 或从 tableView 中删除一个单元格并尝试滑动,​​该单元格就会移动到 tableView 更改之前的先前位置(如果一个单元格是向下一个单元格删除,如果添加了一个单元格,则增加一个单元格)。据我所知,这是因为单元格的框架在 tableView 中的位置发生变化时没有更新,因此位置的 y 坐标不同步。我试过 [self setNeedsDisplay] 和我能找到的所有其他“更新视图”方法,但无济于事。

我正在创建上面引用的动画师,如下所示:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:[self tableView]];
4

1 回答 1

0

看起来问题出在几个不同的地方:

  1. 您的动画师正在使用您的整个表格视图作为参考视图进行初始化。
  2. 然后,您将在tableView的坐标系中使用 midY 锚点创建附件行为,这意味着您的附件行为现在锚定到tableView 的参考坐标系中的一个点,即单元格中心点所在的位置。我敢打赌,如果您尝试滚动 tableView,也会发生奇怪的事情。

根据您的动态行为目标,您需要修改动画师的参考框架和附件的锚点,以完全定义您要实现的物理模拟。基于上述情况,您似乎只是在尝试简单地移动平底锅上的整个单元格。我建议您尝试仅在视图层次结构中移动特定的容器视图,因为表格视图将使用框架直接放置您的单元格。

如果您希望在取消时提供具有回弹效果的平移,那么使用几个 UIAttachmentBehavior 实例可能会更好地实现此效果。一个行为实例用于锚定您想要滑动到其静止位置的视图,另一个用于实际执行平移并移动视图,就像您在平移期间所做的那样。damping您可以通过更改和来调整两个交互之间的交互frequency这个问题对于使用动态项目进行一般拖动是一个很好的参考。

总之,要解决您当前的问题:

  1. 定义动画师对单元坐标系的参考范围,最好使用cell.contentView
  2. 让您的单元直接管理动画师,因为动画师应该只关心其坐标系中的视图。您的动画师不应该知道表格视图的视图层次结构。从您的单元格的动画师中添加/删除 UIDynamicBehavior 项目。
于 2014-03-08T00:10:52.737 回答