7

我正在尝试使用 touches 移动方法将 UIView - “A”(子视图)移动到另一个 UIView - “B”(SuperView)中。我可以将 UIView 移到超级视图之外。我想将 UIView 限制在 Superview 范围内。有什么方法可以测试子视图是否在父视图的可见矩形内?

4

4 回答 4

6

使用 clipsToBounds 方法或CGRectContainsRect

youSuperView.clipsToBounds = YES;

我想对你会有帮助

于 2012-08-10T06:06:24.367 回答
6

听起来您想将子视图(viewA)的移动限制为始终完全包含在父视图(viewB)中。CGRectContainsRect 是正确的答案,但必须小心应用,因为子视图框架是在其父视图的坐标系中指定的。

// inside touches moved, compute the newViewAFrame based on the movement
// but only assign it if it meets the containment constraint:

if (CGRectContainsRect(viewB.bounds, newViewAFrame)) {
    viewA.frame = newViewAFrame;
}

请注意,我们没有在检查中提及 viewB.frame。viewB 在其父级中的位置与 viewB 是否包含 viewA 无关。

于 2012-08-10T07:28:57.443 回答
1

我遇到了同样的问题,这篇文章对我帮助很大,所以我会分享我的答案(这似乎完全符合你的需要):

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if (SuperView.frame.contains(self.frame)) {
            let oldCenter = self.center
            self.center = touch.location(in: SuperView)
            if(!SuperView.frame.contains(self.frame)) {
                self.center = oldCenter
            }
        }
    }
}

非常简单,您也可以在方法中使用touchesMovedtouchesEnded,因此当您的 UIView 达到限制时它不会阻止您(这就是 oldCenter 存在的原因)。

正如@dahn 所说,如果您的视图位于 SuperView 内部,则必须小心,因为第一个的坐标将限制在第二个的框架内,因此如果 SuperView 不是全屏视图,则可能会失败

如果不是全屏视图,SuperView 不能是 SubView 的父亲,因为这会导致 bug。解决方案是将 SuperView 和 SubView 都保留在第三个 View 中(因此它们的坐标系将相同并且可以正常工作)。

希望有一天能对某人有所帮助:)

于 2017-01-14T00:17:07.320 回答
0

斯威夫特 2.2: let rect1 = CGRect(...) let rect2 = CGRect(...)

有一种方法可以检查 -CGRectContainsRect(rect1, rect2)

于 2012-08-10T06:03:23.210 回答