多个UIView重叠 [英] Multiple UIView's overlapping

查看:120
本文介绍了多个UIView重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在自定义UIView中创建多个自定义UIView's.可以创建自定义子视图.他们看起来像这样:

I am creating multiple custom UIView's in a custom UIView. The creation of the custom sub-views is ok. They look like this:

draw方法非常简单:

The draw method is quite straightforward:

[[UIColor brownColor] set];

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx,
                      5.0f);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 0.0f, 0.0f);
CGContextAddLineToPoint(ctx, 100.0f, 0.0);
CGContextAddLineToPoint(ctx, 130.0f, 25.0f);
CGContextAddLineToPoint(ctx, 100.0f, 50.0f);
CGContextAddLineToPoint(ctx, 0.0f, 50.0f);
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
[super drawRect:rect];

将其添加到超级视图也很简单:

Adding it to the super view is also quite simple:

    ITContextFigure *view = [[ITContextFigure alloc] initWithFrame:CGRectMake(location.x, location.y, 135.0f, 50.0f)];
    [view setBackgroundColor:[UIColor yellowColor]];
    [self addSubview:view];

所以我的问题是:

1)如何检测一个何时与另一个重叠?

我看到了这个解决方案:

I saw this solution:

if (CGRectContainsRect([myImageView1 frame], [myImageView2 frame])) {
        NSLog(@"Overlaped, it's working!");
}

但是,如果我有多个UIViews,则在super view上执行for并检查每个子视图对于我来说似乎不是一个好的解决方案.

But if I have multiple UIViews, doing a for on the super view and checking every single sub-view doesn't seem a good solution for me.

2)在这种情况下,该怎么办?

我的主要目标是检测何时发生这种情况:

My main goal is to detect when this happens:

更新1.0

要尝试在此处中显示的内容,不是更优雅的方式.如果我能够实现它,那么如果有人需要,我会将代码发布在Github上.

Going to try what has been showed here, since there isn't a more elegant way. If I am able to achieve it, I will post the code on Github, if anyone needs it.

推荐答案

通过巧妙地对数据进行排序(这些方法称为扫描线或渗透线算法),您可以大大减少所需的碰撞检测次数.下面概述了如何将这种技术应用于您的情况.

You can dramatically cut down on the number of collision detections you need to do by cleverly sorting your data (these are called scan line or seep line algorithms). Here's an outline of how you might apply this technique to your situation.

将子视图排序为按y升序排列的数组.如果两个子视图共享相同的y,则将x升序对它们进行排序.这是您的无效列表,它构成了算法的主要输入.

Sort your subviews into an array ordered by ascending y. If two subviews share the same y order them by ascending x. This is your inactive list and this forms the main input to the algorithm.

算法进行如下.

  1. 尽管有不活动的子视图,请选择一个active_y.这是非活动列表上第一个子视图的y坐标.

  1. While there are inactive subviews, choose an active_y. This is the y coordinate of the first subview on the inactive list.

将所有起源于active_y行的子视图移动到工作列表中,并按x升序进行排序.这是活动列表.

Move all subviews with origins on the active_y line to a working list, sorted by ascending x. This is the active list.

贯穿活动列表,对每个子视图与列表中的后续子视图进行碰撞测试.您可以使用列表中的两个索引来完成此操作(我们将其称为leftright).一旦看到不能与left相交的right子视图,就可以推进left索引.

Run through the active list collision testing each each subview with subsequent ones on the list. You do this using two indices into the list (let's call them left and right). As soon as you see a right subview that cannot intersect with the left you can advance the left index.

在进行碰撞检测时,您还要检查子视图是否现在完全在active_y下面.完成后,您应该将其从活动列表中删除.

While doing the collision detection you also check to see if a subview is now completely below the active_y. Once it is, you should remove it from the active list.

当非活动列表上的所有子视图都已被消耗并且活动列表的最后一次运行完成时,该算法完成.

The algorithm completes when all the subviews on the inactive list have been consumed and the final run through the active list completed.

此算法大大减少了您需要执行的冲突检测次数,大约为O(n log n),但它也可以简化冲突检测本身.

This algorithm greatly cuts down on the number of collision detections you will need to perform and is roughly O(n log n), but it can also simplify the collision detection itself.

由于活动列表是从左到右排序的,因此您在执行检测程序时总是知道哪个在左边,哪个在右边.因此,例如,在比较示例中的箭头形状时,您仅需要检查右侧形状的两个最左侧顶点是否在左侧形状内.您可能会发现CGPathContainsPoint有用.

Since the active list is sorted left to right you always know when you are doing you detection routine which one is on the left and which is on the right. So, for example, when comparing the arrow shapes in your example you only need to check whether the the two leftmost vertices of the right shape fall within the left shape. You may find CGPathContainsPoint useful.

如果要处理的不同形状的数量增加,则可能需要考虑将碰撞检测推入扫描线算法本身.这有点棘手,但从根本上讲,列表将代替包含子视图指针的列表,而将包含构成形状的线段(不包括水平线段).

If the number of distinct shapes you are dealing with increases then you might need to consider pushing the collision detection into the scan line algorithm itself. This is a little trickier, but basically instead of the list holding subview pointers they would hold line segments that make up the shapes (excluding horizontal ones).

这篇关于多个UIView重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆