Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a UIView is out of its superview bounds

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.

like image 551
mlevi Avatar asked Dec 09 '14 17:12

mlevi


People also ask

How do I know if a Viewcontroller is visible?

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.

What is the difference between frame and bounds in UIView?

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.

When should I use layoutSubviews?

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.


2 Answers

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
}
like image 115
Stephen Johnson Avatar answered Oct 19 '22 06:10

Stephen Johnson


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
}
like image 28
filletofish Avatar answered Oct 19 '22 06:10

filletofish