我有一个UIView
,用户可以点按UIView
来“选择”或突出显示它所代表的应用内“内容”。我使用CGRectContainsPoint(thing.frame,tapPoint)
来实现此目标,其中thing.frame
是UIView
的框架,tapPoint
是UITapGestureRecognizer
的抽头点。这很完美。
..除非通过设置UIView
属性(transform
值)来轮换CGAffineTransform
。当UIView
像这样旋转时,frame
变成一个平面正方形,用于封装旋转的视图。
以下是问题的示意图(框架属性标记为A,视觉UIView
bounds
标记为B):
未旋转时
+------------------+
| A == B |
+------------------+
旋转时
+-----------------+
| A . |
| . . |
| . . |
| . . |
| . B . |
| . . |
| . . |
| . |
+-----------------+
我想捕获在rect B
范围内的点击(UIView
的真实界限,旋转),但不是当它们只在rect A
范围内时( frame
的{{1}}属性的值,而不是UIView
。
我如何计算给定的抽头点是否在旋转的B
的真实边界/框架/边界内?有这方便的方法吗?或者我需要使用自己的几何计算UIView
的坐标和尺寸吗?
(如果是后者,请提供一个建议,以便我们尽可能完整地回答。谢谢!)
答案 0 :(得分:10)
你发现了每个人第一次为框架和边界工作时所遇到的一个基本障碍。
框架是视图适合的最小可能(非旋转)矩形,考虑到变换。这意味着,如果您要测试触摸,只要它在最小的可能矩形内,您就可以登录视图周围的可用空间。
对于视觉,想象蓝色方块是转换后的UIView
。视图周围的蓝色边框表示它的框架。注意,即使视图被转换,它的帧仍然是未转换的并处于标准位置。如果frame
传递而不是bounds
,则绿色区域代表可触摸的区域:
另一方面,
Bounds表示接收器的矩形相对于自身,考虑到变换,因此通过传递边界(在-convertPoint:toView:
调用之后)测试视图中的点将正确返回是否或不是给定的触摸(点)与视图相交。
答案 1 :(得分:4)
这里是代码,视图是目标视图,视图是包含该点的源视图。
if(CGRectContainsPoint(viewB.bounds, [viewA convertPoint:point toView:viewB])){
//...
}
答案 2 :(得分:0)
我提出了这个答案,因为我想要一个完整的代码响应解释。如果有人需要代码,为了完整起见,这就是我最终计算视图(containerView)是否完全包含在另一个视图(视图)中的方式:
-(BOOL)viewIsFullyContained:(UIView*)view{
// get the inner rectangle corners in the view coordinate system
CGPoint upperLeft = [self.containerView convertPoint:self.containerView.bounds.origin toView:view];
CGPoint upperRight = [self.containerView convertPoint:CGPointMake(self.containerView.bounds.origin.x + self.containerView.bounds.size.width,
self.containerView.bounds.origin.y)
toView:view];
CGPoint lowerLeft = [self.containerView convertPoint:CGPointMake(self.containerView.bounds.origin.x,
self.containerView.bounds.origin.y + self.containerView.bounds.size.height)
toView:view];
CGPoint lowerRight = [self.containerView convertPoint:CGPointMake(self.containerView.bounds.origin.x + self.containerView.bounds.size.width,
self.containerView.bounds.origin.y + self.containerView.bounds.size.height)
toView:view];
// Check whether all of the corners are fully contained in the view.
BOOL upperLeftIsContained = CGRectContainsPoint(view.bounds, upperLeft);
BOOL upperRightIsContained = CGRectContainsPoint(view.bounds, upperRight);
BOOL lowerLeftIsContained = CGRectContainsPoint(view.bounds, lowerLeft);
BOOL lowerRightIsContained = CGRectContainsPoint(view.bounds, lowerRight);
NSLog(@"Checking for (%i/%i/%i/%i)",upperLeftIsContained,upperRightIsContained,lowerLeftIsContained,lowerRightIsContained);
return (upperRightIsContained && upperRightIsContained && lowerRightIsContained && lowerLeftIsContained);
}