ios - 如何检查 UIImageView 是否与任何其他 View 发生冲突?

标签 ios ios4

我有一个 UIImageView 和一些 UIImageView 在一段时间后进入屏幕。我想检查一个 ImageView 是否与其他任何碰撞。

请帮我。

最佳答案

检测矩形 View 之间冲突的一般过程是使用 CGRectIntersectsRect() 查看两个 View 的框架是否相交。所以,如果你有一个 NSMutableArrayUIImageView对象,您可以通过它们执行快速枚举并查找碰撞,例如:

for (UIView* view in self.imageViewsArray)
{
    if (CGRectIntersectsRect(view.frame, viewToDetectCollisionWith.frame))
    {
        // do whatever you want when you detect the collision
    }
}

或者,您可以使用 enumerateObjectsUsingBlock它使用快速枚举,但同时为您提供数字索引 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动画中间的各种 View 。 CADisplayLink每次动画进行时都会通知您的应用程序,因此您可以在动画进行时获取有关 View 位置的信息。听起来您并没有利用内置动画技术,而是使用 NSTimer手动调整帧,所以你可能不需要下面的代码。但是,如果您曾经追求更自动化的动画,则可以使用以下技术。

你可以做的是使用 CADisplayLink 在动画进行时获取有关屏幕的信息:
#import <QuartzCore/QuartzCore.h>

CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkHandler)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

您甚至可能希望将其存储在类属性中,以便在 View 出现和消失时添加和删除它:
- (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;
}

然后,你可以开始你的动画了。我只是使用标准的基于 block 的动画来不断地为两个 ImageView 帧的变化设置动画,但显然你会做任何适合你的应用程序的事情:
[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 , 到你的项目。见Project Editor Help .

关于ios - 如何检查 UIImageView 是否与任何其他 View 发生冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13806198/

相关文章:

ios - Swift 中的 NSFastEnumeration

ios - 快速更改所选标签栏图标的颜色

objective-c - 如何为 iPad 应用程序创建主视图

iphone - 如何在iphone项目中包含FFMpeg库

iphone - 添加依赖于scrollView.contentSize的 subview 的正确位置是什么?

ios - 如何使用 eventKit 框架为特定日期设置提醒(警报)

ios - 旋转期间 MKMapView 的 centerCoordinate 出现错误?

ios - UIScrollView/UITableView 设置 ContentOffset 会杀死惯性/滚动吗?

objective-c - 在 Controller 实例变量中存储现有对象时是否需要 'retain'?

iphone - 支持多任务处理的 iOS 4 闹钟应用程序