如何识别两个图像视图在动画移动时的碰撞?

Sam*_*ior 5 objective-c collision-detection uiviewanimation ios

当两个视图发生碰撞时我正在处理警报,这里我使用了两个在不同方向上移动的图像视图,它们会在一个点上发生碰撞.我使用基本的动画代码在各自的方向上移动这些图像.(注意: - 不仅如下图所示,但是如果它们在方面发生碰撞我们需要显示警报)

在此输入图像描述 在此输入图像描述

Rob*_*Rob 7

如果使用标准视图动画(例如基于块animateWithDuration),您可以设置CADisplayLink(类似于计时器,但每次更新显示时调用),然后比较frame两个视图的值并查看它们是否相交.但诀窍在于,在动画期间,frame视图是"最终目标"框架,因此如果您想要在frame动画进行过程中使用它,可以查看其"表示层".

- (void)startDisplayLink
{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)stopDisplayLink
{
    [self.displayLink invalidate];
    self.displayLink = nil;
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
    CALayer *view1PresentationLayer = self.view1.layer.presentationLayer;
    CALayer *view2PresentationLayer = self.view2.layer.presentationLayer;

    if (CGRectIntersectsRect(view1PresentationLayer.frame, view2PresentationLayer.frame)) {

        NSLog(@"collision");                              // report the collision; show alert if you want

        [self.view1.layer removeAllAnimations];           // stop the animation if you want
        [self.view2.layer removeAllAnimations];

        self.view1.frame = view1PresentationLayer.frame;  // but make sure to reset the frame to be the current position
        self.view2.frame = view2PresentationLayer.frame;

        [self stopDisplayLink];                           // stop the display link if we don't need it any more
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的方法中,我假设你想要停止动画(这不仅涉及删除动画,而是重置最终目的地以反映当前视图的位置),但是做你想做的任何事情.

因此,您可以启动显示链接,启动动画,显示链接选择器方法将告诉我们是否存在冲突:

[self startDisplayLink];

[UIView animateWithDuration:1.0 animations:^{
    self.view1.frame = CGRectMake(...);
    self.view2.frame = CGRectMake(...);
}];
Run Code Online (Sandbox Code Playgroud)

请注意,在iOS 7中,您可能需要查看UIKit Dynamics,您可以在其中添加行为以驱动视图的移动,还可以定义a UICollisionBehavior以识别何时发生此类冲突.使用UIKit Dynamics可能超出了这个问题的范围,但您应该参考Apple的WWDC 2013视频UIKit动态UIKit Dynamics 高级技术入门.

但是,例如,在iOS 7中,您可以放弃animateWithDuration使用UIKit动力学,然后使用UIKit动画制作动画,您可以在其中告诉两个视图捕捉屏幕上的特定位置,但检测它们何时发生碰撞:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.view1, self.view2]];
itemBehavior.allowsRotation = NO;
itemBehavior.resistance = 10.0;  // you can change this to affect the speed of the attachment behaviors
[self.animator addBehavior:itemBehavior];

UISnapBehavior *snap1 = [[UISnapBehavior alloc] initWithItem:self.view1 snapToPoint:newPoint1];
[self.animator addBehavior:snap1];

UISnapBehavior *snap2 = [[UISnapBehavior alloc] initWithItem:self.view2 snapToPoint:newPoint2];
[self.animator addBehavior:snap2];

// You can, alternatively use the following attachment behaviors, instead of the above
// snap behaviors, and you can then use resistance to control the speed with which they move
//
// UIAttachmentBehavior *attachment1 = [[UIAttachmentBehavior alloc] initWithItem:self.view1 attachedToAnchor:self.view1.center];
// [self.animator addBehavior:attachment1];
// attachment1.frequency = 1.0;
// attachment1.anchorPoint = newPoint1;
//
// UIAttachmentBehavior *attachment2 = [[UIAttachmentBehavior alloc] initWithItem:self.view2 attachedToAnchor:self.view2.center];
// [self.animator addBehavior:attachment2];
// attachment2.frequency = 1.0;
// attachment2.anchorPoint = newPoint2;

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.view1, self.view2]];
collision.collisionDelegate = self;
[self.animator addBehavior:collision];
Run Code Online (Sandbox Code Playgroud)

并且有一个UICollisionBehaviorDelegate方法可以在发生碰撞时执行某些操作,例如删除行为,有效地结束动画:

- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item1 withItem:(id<UIDynamicItem>)item2 atPoint:(CGPoint)p
{
    [self.animator removeAllBehaviors];  // for example, if they collide, you could remove the behaviors so they stop

    // show alert if you want to
}
Run Code Online (Sandbox Code Playgroud)


Gar*_*d81 2

如果您的目标是 iOS 7 及更高版本,那么您可以查看 UIKit Dynamics

https://developer.apple.com/library/ios/samplecode/DynamicsCatalog/Introduction/Intro.html