【问题标题】:How to check if a UIView is out of its superview bounds如何检查 UIView 是否超出其超级视图范围
【发布时间】:2015-02-07 17:22:44
【问题描述】:

我有一个带有平移手势的视图和一个连接到它的 UIPushBehavior,我想知道是否可以检查视图何时超出超级视图边界。基本上用户扔视图,我想在视图超出屏幕时运行一些动画。无法弄清楚如何做到这一点。谢谢。

【问题讨论】:

    标签: ios objective-c iphone swift uiview


    【解决方案1】:

    如果你想检查它是否完全超出了它的超级视图范围,你可以这样做

    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
    }
    

    【讨论】:

    • 刚试过这个,似乎即使视图仍在超级视图的范围内,它也会被调用:/
    • 如果它有帮助我正在做的事情是基于本教程:raywenderlich.com/71828/uikit-dynamics-tutorial-tossing-views
    • 基本上我想在视图离开屏幕后做一些事情
    • 对不起,我误解了你的问题。您需要将该代码放入手势识别器的操作中。
    • 这样做了,即使视图仍在边界内,我放入的代码也会被调用
    【解决方案2】:

    编辑
    正如所指出的,这个答案并不完全正确,请参考更受欢迎的答案。

    在 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】:

      不幸的是,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】:

        斯威夫特 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
            }
        

        【讨论】:

          【解决方案5】:

          已接受答案的 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
          }
          

          【讨论】:

          • 非常感谢您的回答。
          【解决方案6】:

          如果您想检查子视图的一部分是否超出其超级视图的范围,请尝试以下操作:

          在x轴的情况下

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

          你可以对 y 轴尝试同样的方法,将 minX 和 maxX 替换为 minY 和 maxY

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-12-16
            • 1970-01-01
            • 1970-01-01
            • 2017-07-21
            • 2018-07-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多