我正在尝试使用 touches 移动方法将 UIView - “A”(子视图)移动到另一个 UIView - “B”(SuperView)中。我可以将 UIView 移到超级视图之外。我想将 UIView 限制在 Superview 范围内。有什么方法可以测试子视图是否在父视图的可见矩形内?
4 回答
使用 clipsToBounds 方法或CGRectContainsRect
youSuperView.clipsToBounds = YES;
我想对你会有帮助
听起来您想将子视图(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 无关。
我遇到了同样的问题,这篇文章对我帮助很大,所以我会分享我的答案(这似乎完全符合你的需要):
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
}
}
}
}
非常简单,您也可以在方法中使用touchesMoved
它touchesEnded
,因此当您的 UIView 达到限制时它不会阻止您(这就是 oldCenter 存在的原因)。
正如@dahn 所说,如果您的视图位于 SuperView 内部,则必须小心,因为第一个的坐标将限制在第二个的框架内,因此如果 SuperView 不是全屏视图,则可能会失败。
如果不是全屏视图,SuperView 不能是 SubView 的父亲,因为这会导致 bug。解决方案是将 SuperView 和 SubView 都保留在第三个 View 中(因此它们的坐标系将相同并且可以正常工作)。
希望有一天能对某人有所帮助:)
斯威夫特 2.2:
let rect1 = CGRect(...)
let rect2 = CGRect(...)
有一种方法可以检查 -CGRectContainsRect(rect1, rect2)