多个UIView的重叠
我在自定义UIView's
创build多个自定义UIView
。 自定义子视图的创build是可以的。 他们看起来像这样:
绘制方法非常简单:
[[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];
将它添加到超级视图也很简单:
ITContextFigure *view = [[ITContextFigure alloc] initWithFrame:CGRectMake(location.x, location.y, 135.0f, 50.0f)]; [view setBackgroundColor:[UIColor yellowColor]]; [self addSubview:view];
所以我的问题是:
1)如何检测一个与另一个重叠?
我看到这个解决scheme:
if (CGRectContainsRect([myImageView1 frame], [myImageView2 frame])) { NSLog(@"Overlaped, it's working!"); }
但是,如果我有多个UIViews
,在super view
上做一个for
并检查每个子视图对我来说似乎不是一个好的解决scheme。
2)在这种情况下,可以做些什么?
我的主要目标是检测这种情况发生的时间:
更新1.0
去试试这里已经显示的东西 ,因为没有更优雅的方式。 如果我能够实现它,我会在Github上发布代码,如果有人需要的话。
您可以通过巧妙地对数据进行sorting(这些称为扫描线或渗透线algorithm),大幅减less您需要执行的碰撞检测次数。 以下是您如何将这一技巧应用于您的情况的大纲。
将你的子视图按照y的顺序sorting。 如果两个子视图共享相同的y按顺序升序x。 这是你的非活动列表,这构成了algorithm的主要input。
algorithm进行如下。
-
虽然有不活动的子视图,请select一个
active_y
。 这是非活动列表中第一个子视图的y坐标。 -
将所有具有
active_y
行上的active_y
子视图移动到工作列表,按升序xsorting。 这是活动列表。 -
通过活动列表冲突testing每个子视图与列表中的后续列表。 你在列表中使用两个索引(让我们称它们为
left
和right
)。 只要你看到一个不能与left
相交的right
子视图,你可以前进left
索引。 -
在进行碰撞检测的同时,您还要检查子视图是否现在完全位于
active_y
。 一旦它,你应该从活动列表中删除它。
当非活动列表中的所有子视图都已被占用并且完成了活动列表的最终运行时,该algorithm将完成。
这个algorithm大大减less了你需要执行的碰撞检测次数,大概是O(n log n),但它也可以简化碰撞检测本身。
由于活动列表是从左到右sorting的,所以你总是知道你在做什么检测程序,哪一个在左边,哪个在右边。 因此,例如,在比较示例中的箭头形状时,只需检查右侧形状的两个最左侧顶点是否落在左侧形状内。 您可能会发现CGPathContainsPoint
有用。
如果您正在处理的不同形状的数量增加,那么您可能需要考虑将碰撞检测推入扫描线algorithm本身。 这是有点棘手,但基本上,而不是持有子视图指针的列表,他们将持有组成形状(不包括水平的)的线段。