mlevi
mlevi

Reputation: 1463

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.

Upvotes: 18

Views: 10620

Answers (6)

Sibi 75
Sibi 75

Reputation: 1

if you want to check if part of the subview is out of bounds of its super view, try this:

in case of x axis

if subview.frame.maxX >= superview.bounds.maxX {
    your code 
}
if subview.frame.minX <= superview.bounds.minX {
    your code
}

you can try the same for y axis, replace minX and maxX to minY and maxY

Upvotes: 0

Teffi
Teffi

Reputation: 2508

Swift 5 version on accepted answer:

// Full
if subview.superview!.bounds.contains(subview.frame) { 
  // Do something 
}

// Partial
let intersection = subview.superview!.bounds.intersection(subview.frame)
if !intersection.equalTo(subview.frame) { 
  // Do something
}

Upvotes: 2

Volodymyr Kuzomenskyi
Volodymyr Kuzomenskyi

Reputation: 540

Swift 5

func isView(_ innerView: UIView, outOfViewFrame outerViewFrame: CGRect) -> Bool {
        let intersectedFrame = outerViewFrame.intersection(innerView.frame)
        let isInBounds = abs(intersectedFrame.origin.x - innerView.frame.origin.x) < 1 &&
            abs(intersectedFrame.origin.y - innerView.frame.origin.y) < 1 &&
            abs(intersectedFrame.size.width - innerView.frame.size.width) < 1 &&
            abs(intersectedFrame.size.height - innerView.frame.size.height) < 1
        return !isInBounds
    }

Upvotes: 3

Philipp
Philipp

Reputation: 61

EDIT
As pointed out, this answer is not entirely correct, please refer to the more upvoted one.

In Swift 3:

    let v1 = UIView()
    v1.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
    v1.backgroundColor = UIColor.red
    view.addSubview(v1)

    let v2 = UIView()
    v2.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
    v2.backgroundColor = UIColor.blue
    view.addSubview(v2)

    if (v1.bounds.contains(v2.frame))
    {
        //view is completely inside super view.
    }
    //this should be an or test
    if (v1.bounds.intersection(v2.frame).width > 0) || (v1.bounds.intersection(v2.frame).height > 0)
    {
        //view is partially out of bounds
    }

Upvotes: 4

filletofish
filletofish

Reputation: 343

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
}

Upvotes: 6

Stephen Johnson
Stephen Johnson

Reputation: 5121

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
}

Upvotes: 24

Related Questions