简体   繁体   English

限制超视图内的视图

[英]restrict a view inside the superview

I'm trying to move a UIView - "A" (Subview) inside another UIView - "B" (SuperView) using the touches moved method.我正在尝试使用触摸移动方法移动另一个 UIView - “B”(SuperView)内的 UIView - “A”(子视图)。 I'm able to move the UIView outside the superview.我可以将 UIView 移动到超级视图之外。 I want to restrict the UIView inside the Superview bounds.我想限制 Superview 边界内的 UIView。 Is there any way there can be a generic method to test if the subview is inside the visible rect of the superview ???有什么办法可以有一个通用的方法来测试子视图是否在超级视图的可见矩形内???

Use clipsToBounds method or CGRectContainsRect使用 clipsToBounds 方法或CGRectContainsRect

youSuperView.clipsToBounds = YES;

I think it will be helpful to you我认为它会对你有所帮助

It sounds like you want to constrain the movement of the subview (viewA) to be always completely contained by the superview (viewB).听起来您想限制子视图 (viewA) 的移动,使其始终完全被父视图 (viewB) 包含。 CGRectContainsRect is the right answer, but it must be applied carefully, since a subview frame is specified in it's superview's coordinate system. 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;
}

Notice that we don't mention viewB.frame in the check.请注意,我们没有在检查中提及 viewB.frame。 viewB's position in it's parent is not relevant to whether viewB contains viewA. viewB 在其父级中的位置与 viewB 是否包含 viewA 无关。

I had the same problem and this post helped me a lot, so I'll share my answer (that seems to fit exactly what you need) :我遇到了同样的问题,这篇文章对我帮助很大,所以我将分享我的答案(这似乎完全符合您的需要):

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
            }
        }
    }
}

quite simple and you can use this in the methods touchesMoved and touchesEnded too, so it won't stop you when your UIView reach the limits (this is why oldCenter exists).非常简单,您也可以在touchesMovedtouchesEnded方法中使用它,因此当您的 UIView 达到限制时它不会阻止您(这就是 oldCenter 存在的原因)。

As mentioned by @dahn, if your view is INSIDE the SuperView, you must take care, because the coordinates of the first will be restrict to the frame of the second, so it may fail if the SuperView is not a full-screen view .正如@dahn 提到的,如果您的视图在 SuperView 内部,则必须小心,因为第一个的坐标将限制在第二个的框架内,因此如果 SuperView 不是全屏视图它可能会失败

If it is not a full-screen view, the SuperView cannot be the dad of the SubView , because it will cause bugs.如果不是全屏视图,则 SuperView 不能成为 SubView 的父亲,因为它会导致错误。 The solution is to keep the SuperView and the SubView both inside a third View (so their coordinate system will be the same and it will work fine).解决方案是将 SuperView 和 SubView 都保留在第三个 View 中(因此它们的坐标系将相同并且可以正常工作)。

Hope that helps someone someday :)希望有一天能帮助某人:)

Swift 2.2: let rect1 = CGRect(...) let rect2 = CGRect(...) Swift 2.2: let rect1 = CGRect(...) let rect2 = CGRect(...)

There is a method to check this - CGRectContainsRect(rect1, rect2)有一种方法可以检查这个 - CGRectContainsRect(rect1, rect2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM