如何检查一个UIView是否超出其父视图的边界

17

我有一个视图,使用手势和UIPushBehavior,想知道是否可能检查该视图何时超出父视图的界限。基本上,用户扔掉视图时,当视图不在屏幕中时,我想运行一些动画。无法弄清楚如何实现这一点。谢谢。

6个回答

23

如果你想检查它是否完全超出了其父视图的边界,你可以这样做

if (!CGRectContainsRect(view.superview.bounds, view.frame))
{
    //view is completely out of bounds of its super view.
}

如果你想检查只有部分是否超出界限,可以这样做:

if (!CGRectEqualToRect(CGRectIntersection(view.superview.bounds, view.frame), view.frame))
{
   //view is partially out of bounds
}

2
刚试了一下,似乎即使视图仍在父视图的范围内,它也会被调用 :/ - mlevi
基本上,我想在视图离开屏幕后执行某些操作。 - mlevi
抱歉,我误解了你的问题。你需要将那段代码放在手势识别器的动作中。 - Stephen Johnson
这样做后,即使视图仍在边界内,我放置的代码也会被调用。 - mlevi
只需创建识别器和带有检查视图是否越界的操作方法。 - Stephen Johnson
显示剩余3条评论

6

很不幸,Philipp 对部分越界检查的答案在这行代码中并不完全正确: v1.bounds.intersection(v2.frame).width > 0) && (v1.bounds.intersection(v2.frame).height > 0

交集大小可以大于零,但视图仍可能位于父视图边界内。

此外,由于 CGFloat 的精度问题,我无法安全地使用 equal(to: CGRect)

这里是已经纠正的版本:

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
}

4

编辑
正如指出的那样,这个答案并不完全正确,请参考更多赞的答案。

在 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
    }

3

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
    }

2

以下是接受答案的Swift 5版本:

// 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
}

0

如果您想检查子视图的部分是否超出其父视图的边界,请尝试以下方法:

对于x轴情况

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

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

你可以尝试对y轴进行相同的操作,将minX和maxX替换为minY和maxY


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接