简体   繁体   中英

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. I'm able to move the UIView outside the superview. I want to restrict the UIView inside the Superview bounds. 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

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). CGRectContainsRect is the right answer, but it must be applied carefully, since a subview frame is specified in it's superview's coordinate system.

// 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's position in it's parent is not relevant to whether viewB contains 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).

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 .

If it is not a full-screen view, the SuperView cannot be the dad of the SubView , because it will cause bugs. 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).

Hope that helps someone someday :)

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

There is a method to check this - CGRectContainsRect(rect1, rect2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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