4

我试图UICollisionBehavior在 UIKit Dynamics 中使用来确定我已经抛出屏幕(使用UIAttachmentBehaviorand UIPushBehavior)的视图实际上何时完全离开屏幕。

我发现它很复杂,因为我无法在它的进程中跟踪它,一旦它被抛出,我试图弄清楚UICollisionBehavior它的最后一个边缘何时与它的超级视图“碰撞”。与 NSTimer 解决方案或类似的解决方案相比,这似乎是确定它何时不在屏幕上的最简单方法(但如果你能想到任何更简单的方法,我会全力以赴!)。

我在这个项目中看到的一个解决方案(特别是这里)如下:

CGRect referenceBounds = self.animator.referenceView.bounds;
CGFloat inset = -hypot(CGRectGetWidth(referenceBounds), CGRectGetHeight(referenceBounds));
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(inset, inset, inset, inset);
[self.collisionBehavior setTranslatesReferenceBoundsIntoBoundaryWithInsets:edgeInsets];

它计算我猜测的碰撞边界在哪里(老实说,我并不完全理解它),然后当检测到碰撞时调用委托时我调用removeFromSuperview.

但无论出于何种原因,这都非常不可靠。有时我会把它从屏幕上扔掉,它实际上永远不会以某种方式调用碰撞检测委托。通常时机也会有点晚。

就我的设置而言,它只是将 UIScrollView 扔出屏幕,其框架设置为其超级视图的边界(self.view在视图控制器中)。

有没有更好的方法来为它离开视图时设置碰撞检测?

4

1 回答 1

4

这个答案中,我说明了如何使用 UIKit Dynamics 处理将视图拖动到屏幕外。具体来说,我建议不要使用UICollisionBehavior(或其他),而是指定一个块来检查视图何时不再相交。这说明了使用 a 时的想法,但该想法适用于任何 UIKit 动态行为:NSTimeractionUIDynamicItemBehavior

UIDynamicItemBehavior *dynamic = [[UIDynamicItemBehavior alloc] initWithItems:@[viewToAnimate]];
[dynamic addLinearVelocity:velocity forItem:viewToAnimate];
[dynamic addAngularVelocity:angularVelocity forItem:viewToAnimate];

// when the view no longer intersects with its superview, go ahead and remove it

typeof(self) __weak weakSelf = self;
dynamic.action = ^{
    if (!CGRectIntersectsRect(gesture.view.superview.bounds, gesture.view.frame)) {
        [weakSelf.animator removeAllBehaviors];
        [viewToAnimate removeFromSuperview];
    }
};

// now add dynamic behavior

[self.animator addBehavior:dynamic];

显然,您应该自定义它以适合您的特定场景,但希望它能够说明这个想法。

于 2014-03-02T16:25:21.013 回答