I have a view with a pan gesture and a UIPushBehavior hooked up to it an wanted to know if its possible to check when the view is out the superviews bounds. Basically the user tosses the view and I want to run some animation when the view is out of the screen. Couldn't figure out how to do this. Thanks.
The view's window property is non-nil if a view is currently visible, so check the main view in the view controller: Invoking the view method causes the view to load (if it is not loaded) which is unnecessary and may be undesirable. It would be better to check first to see if it is already loaded.
The bounds of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to its own coordinate system (0,0). The frame of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to the superview it is contained within.
layoutSubviews() The system calls this method whenever it needs to recalculate the frames of views, so you should override it when you want to set frames and specify positioning and sizing. However, you should never call this explicitly when your view hierarchy requires a layout refresh.
If you want to check if it is entirely out of it's superview bounds you can do this
if (!CGRectContainsRect(view.superview.bounds, view.frame))
{
//view is completely out of bounds of its super view.
}
If you want to check if just part of it is out of bounds you can do
if (!CGRectEqualToRect(CGRectIntersection(view.superview.bounds, view.frame), view.frame))
{
//view is partially out of bounds
}
Unfortunately, Philipp's answer on partially out of bounds check is not fully correct in this line:
v1.bounds.intersection(v2.frame).width > 0) && (v1.bounds.intersection(v2.frame).height > 0
Intersection size can be bigger than zero and still the view would lie inside the superview bounds.
Also it turned out that I can't use equal(to: CGRect)
safely because of CGFloat accuracy.
Here is corrected version:
func outOfSuperviewBounds() -> Bool {
guard let superview = self.superview else {
return true
}
let intersectedFrame = superview.bounds.intersection(self.frame)
let isInBounds = fabs(intersectedFrame.origin.x - self.frame.origin.x) < 1 &&
fabs(intersectedFrame.origin.y - self.frame.origin.y) < 1 &&
fabs(intersectedFrame.size.width - self.frame.size.width) < 1 &&
fabs(intersectedFrame.size.height - self.frame.size.height) < 1
return !isInBounds
}
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