判断UIView是否被其他view覆盖?

Determine whether UIView is covered by other views?

我正在构建一个简单的纸牌游戏,其中的纸牌会轻弹到中央牌堆上,我想在数字太大时开始移除底部的纸牌。但是,我对每张卡片应用了一些随机旋转和定位,这意味着其中一些卡片的角突出等。这是屏幕截图:

我想做的是确定视图的任何部分是否对用户可见,并删除任何被其他视图完全覆盖的部分。

view都是实例化的,都在同一个superview里面,都在view的bounds之内,所以用这些方法是行不通的。我需要查明一个视图是否已被其他视图完全覆盖,此时我可以安全地删除它而不会让用户看到任何东西消失。

从概念上讲,您想要向下迭代堆栈,将卡片的路径并入累积路径,然后检查该并集路径是否与 下一个 并集路径相等。换句话说,如果向下添加下一条路径不会更改并集路径,那么它 必须 被完全遮盖,因此可以被删除。它可能看起来像这样:

UIBezierPath* accumulator = nil;
for (UIView* cardView in [[[containingView subviews] copy] reverseObjectEnumerator])
{
    UIBezierPath* p = GetPathForView(cardView);
    UIBezierPath* next = PathByUnioningPaths(p, accumulator);

    if ([next isEqual: accumulator])
    {
        // This view is completely obscured, remove it
        [cardView removeFromSuperview];
    }

    accumulator = next;
}

当然,这假定函数 GetPathForViewPathByUnioningPaths 存在。前者将由您编写,具体取决于您创建卡片视图的方式。后者将需要某种贝塞尔路径布尔运算库。我找到了这个,它似乎有一定的吸引力:https://bitbucket.org/martinwinter/vectorbooleancg