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

如果使用标准视图动画(例如基于块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)
如果您的目标是 iOS 7 及更高版本,那么您可以查看 UIKit Dynamics
https://developer.apple.com/library/ios/samplecode/DynamicsCatalog/Introduction/Intro.html
| 归档时间: |
|
| 查看次数: |
775 次 |
| 最近记录: |