我有一个 UIImageView 和一些 UIImageView 在一段时间后进入屏幕。我想检查一个 ImageView 是否与其他任何碰撞。
请帮我。
检测矩形视图之间碰撞的一般过程是用来CGRectIntersectsRect()
查看两个视图的框架是否相交。因此,如果您有一个NSMutableArray
对象UIImageView
,您可以通过它们执行快速枚举并查找碰撞,例如:
for (UIView* view in self.imageViewsArray)
{
if (CGRectIntersectsRect(view.frame, viewToDetectCollisionWith.frame))
{
// do whatever you want when you detect the collision
}
}
或者,您可以使用enumerateObjectsUsingBlock
which 使用快速枚举,但在单个语句中为您提供数字索引idx
和数组中的各个对象:UIView
[self.imageViewsArray enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
if (CGRectIntersectsRect(view.frame, viewToDetectCollisionWith.frame))
{
// do whatever you want when you detect the collision
}
}];
原答案:
如果您UIImageView
通过各种自动动画技术为对象设置动画,则必须使用诸如CADisplayLink
检查碰撞之类的东西,因为 iOS 正在处理动画,否则您不会被告知frame
动画中间的各种视图. 每次动画进行时都会通知您的CADisplayLink
应用程序,因此您可以在动画进行时获得有关视图位置的信息。听起来您没有利用内置动画技术,而是使用 aNSTimer
手动调整帧,因此您可能不需要以下代码。但是,如果您曾经追求更自动化的动画,则可以使用以下技术。
您可以做的是CADisplayLink
在动画进行时使用 a 获取有关屏幕的信息:
#import <QuartzCore/QuartzCore.h>
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkHandler)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
您甚至可能希望将其存储在类属性中,以便在视图出现和消失时添加和删除它:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkHandler)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = nil;
}
然后,你可以开始你的动画了。我只是使用标准的基于块的动画来不断地为两个图像视图帧的变化设置动画,但显然你会做任何适合你的应用程序的事情:
[UIView animateWithDuration:4.0
delay:0.5
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
self.imageView1.frame = ... // I set the frame here
self.imageView2.frame = ... // I set the frame here
}
completion:nil];
现在我可以检测到这两个帧何时与此处理程序发生碰撞(即它们的帧是否相交),该CADisplayLink
处理程序获取相关presentationLayer
属性以获取“进行中”的帧坐标:
- (void)displayLinkHandler
{
id presentationLayer1 = self.imageView1.layer.presentationLayer;
id presentationLayer2 = self.imageView2.layer.presentationLayer;
BOOL nowIntersecting = CGRectIntersectsRect([presentationLayer1 frame], [presentationLayer2 frame]);
// I'll keep track of whether the two views were intersected in a class property,
// and therefore only display a message if the intersected state changes.
if (nowIntersecting != self.wasIntersected)
{
if (nowIntersecting)
NSLog(@"imageviews now intersecting");
else
NSLog(@"imageviews no longer intersecting");
self.wasIntersected = nowIntersecting;
}
}
顺便说一句,您可能需要将 Quartz 2D 添加QuartzCore.framework
到您的项目中。请参阅项目编辑器帮助。