【发布时间】:2015-02-07 17:22:44
【问题描述】:
我有一个带有平移手势的视图和一个连接到它的 UIPushBehavior,我想知道是否可以检查视图何时超出超级视图边界。基本上用户扔视图,我想在视图超出屏幕时运行一些动画。无法弄清楚如何做到这一点。谢谢。
【问题讨论】:
标签: ios objective-c iphone swift uiview
我有一个带有平移手势的视图和一个连接到它的 UIPushBehavior,我想知道是否可以检查视图何时超出超级视图边界。基本上用户扔视图,我想在视图超出屏幕时运行一些动画。无法弄清楚如何做到这一点。谢谢。
【问题讨论】:
标签: ios objective-c iphone swift uiview
如果你想检查它是否完全超出了它的超级视图范围,你可以这样做
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
}
【讨论】:
编辑
正如所指出的,这个答案并不完全正确,请参考更受欢迎的答案。
在 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
}
【讨论】:
不幸的是,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
}
【讨论】:
斯威夫特 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
}
【讨论】:
已接受答案的 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
}
【讨论】:
如果您想检查子视图的一部分是否超出其超级视图的范围,请尝试以下操作:
在x轴的情况下
if subview.frame.maxX >= superview.bounds.maxX {
your code
}
if subview.frame.minX <= superview.bounds.minX {
your code
}
你可以对 y 轴尝试同样的方法,将 minX 和 maxX 替换为 minY 和 maxY
【讨论】: