限制超级视图内的视图
Posted
技术标签:
【中文标题】限制超级视图内的视图【英文标题】:restrict a view inside the superview 【发布时间】:2012-08-10 05:58:15 【问题描述】:我正在尝试使用 touches 移动方法将 UIView - “A”(子视图)移动到另一个 UIView - “B”(SuperView)中。我可以将 UIView 移到超级视图之外。我想将 UIView 限制在 Superview 范围内。有什么办法可以有一个通用的方法来测试子视图是否在父视图的可见矩形内???
【问题讨论】:
您找到解决方案了吗? 是的,它适用于旧版本的ios sdk,我不知道它是否仍然相同,从技术上讲它应该与接受的答案相同 @LalithB 你能发布你的解决方案吗? 【参考方案1】:听起来您想将子视图 (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 无关。
【讨论】:
是的,但是视图在到达边界时停止。盒子到达边界后我无法移动它。我正在尝试复制 UIWebView 的选择框之类的东西(在 www.google.com 上选择并移动时,您会找到它)。最大化和调整盒子大小的手势是一种痛苦。如果有任何控制或示例可以继续,那将是可怕的。 :)【参考方案2】:使用 clipsToBounds 方法或CGRectContainsRect
youSuperView.clipsToBounds = YES;
我觉得对你有帮助
【讨论】:
对于上述情况,CGRectContainsRect 总是返回 false。 clipToBounds 很有帮助,但不应裁剪视图,它应该停止裁剪,在边界上。有什么办法吗?【参考方案3】:我遇到了同样的问题,这篇文章对我帮助很大,所以我会分享我的答案(这似乎完全符合你的需要):
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 中(因此它们的坐标系将相同并且可以正常工作)。
希望有一天能对某人有所帮助:)
【讨论】:
【参考方案4】:斯威夫特 2.2:
let rect1 = CGRect(...)
let rect2 = CGRect(...)
有一种方法可以检查这个 - CGRectContainsRect(rect1, rect2)
【讨论】:
以上是关于限制超级视图内的视图的主要内容,如果未能解决你的问题,请参考以下文章