菜鸟教程小白 发表于 2022-12-13 14:41:46

ios - 多个 UIView 的重叠


                                            <p><p>我正在自定义 <code>UIView</code> 中创建多个自定义 <code>UIView 的</code>。自定义 subview 的创建是好的。它们看起来像这样:</p>

<p> <img src="/image/v2ogC.png" alt="enter image description here"/> </p>

<p>draw 方法很简单:</p>

<pre><code>[ 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);
;
</code></pre>

<p>将其添加到 superView 中也很简单:</p>

<pre><code>    ITContextFigure *view = [ initWithFrame:CGRectMake(location.x, location.y, 135.0f, 50.0f)];
    ];
    ;
</code></pre>

<p>所以我的问题是:</p>

<p><strong>1) 如何检测一个与另一个重叠的时间?</strong> </p>

<p>我看到了这个解决方案:</p>

<pre><code>if (CGRectContainsRect(, )) {
      NSLog(@&#34;Overlaped, it&#39;s working!&#34;);
}
</code></pre>

<p>但如果我有多个 <code>UIViews</code>,在 <code>super view</code> 上执行 <code>for</code> 并检查每个 subview 似乎不是对我来说很好的解决方案。</p>

<p><strong>2) 在这种情况下,可以做什么?</strong></p>

<p> <img src="/image/wRGV0.png" alt="enter image description here"/> </p>

<p><strong>我的主要目标</strong>是检测何时发生这种情况:</p>

<p> <img src="/image/AotKw.png" alt="enter image description here"/> </p>

<hr/>

<p><strong>更新 1.0</strong></p>

<p>将尝试显示的内容<a href="https://stackoverflow.com/questions/7361750/detecting-if-uiview-is-intersecting-other-uiviews" rel="noreferrer noopener nofollow">here</a> ,因为没有更优雅的方式。如果我能够实现它,我会将代码发布到 Github 上,如果有人需要的话。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您可以通过巧妙地对数据进行排序(这些称为扫描线或渗线算法)来显着减少需要执行的碰撞​​检测次数。下面概述了如何将此技术应用于您的情况。</p>

<p>将您的 subview 排序到按 y 升序排序的数组中。如果两个 subview 共享相同的 y,则按升序排列它们。这是您的非事件列表,它构成了算法的主要输入。</p>

<p>算法如下进行。</p>

<ol>
<li><p>虽然有不活动的 subview ,请选择 <code>active_y</code>。这是非事件列表中第一个 subview 的 y 坐标。</p></li>
<li><p>将原点在 <code>active_y</code> 行的所有 subview 移动到工作列表中,按 x 升序排序。这是事件列表。</p></li>
<li><p>通过事件列表碰撞测试每个 subview 与列表中的后续 subview 。您可以使用列表中的两个索引来执行此操作(我们称它们为 <code>left</code> 和 <code>right</code>)。一旦你看到一个不能与 <code>left</code> 相交的 <code>right</code>subview ,你就可以推进 <code>left</code> 索引。 </p></li>
<li><p>在进行碰撞检测时,您还要检查 subview 现在是否完全位于 <code>active_y</code> 之下。一旦出现,您应该将其从事件列表中删除。</p></li>
</ol>

<p>当非事件列表上的所有 subview 都已被消耗并且通过事件列表的最终运行完成时,算法完成。</p>

<p>该算法大大减少了您需要执行的碰撞​​检测次数,大约为 O(n log n),但它也可以简化碰撞检测本身。</p>

<p>由于事件列表是从左到右排序的,因此您在执行检测例程时始终知道哪个在左侧,哪个在右侧。因此,例如,在比较示例中的箭头形状时,您只需检查右侧形状的最左侧两个顶点是否落在左侧形状内。您可能会发现 <code>CGPathContainsPoint</code> 很有用。</p>

<p>如果您要处理的不同形状的数量增加,那么您可能需要考虑将碰撞检测插入扫描线算法本身。这有点棘手,但基本上不是保存 subview 指针的列表,而是保存构成形状的线段(不包括水平线段)。 </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 多个 UIView 的重叠,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/11473189/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/11473189/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 多个 UIView 的重叠