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 ???
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.
Use clipsToBounds method or CGRectContainsRect
youSuperView.clipsToBounds = YES;
I think it will be helpful to you
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With