我有一个UIView
,用户可以点击UIView
为“选择”或突出显示在应用程序的“东西”,它代表。 我用CGRectContainsPoint(thing.frame,tapPoint)
来实现这一点,其中thing.frame
是的帧UIView
,和tapPoint
是从抽头点UITapGestureRecognizer
。 这完美的作品。
..except当UIView
是通过设置旋转transform
特性(具有CGAffineTransform
值)。 当UIView
旋转这样的, frame
成为平坦正方形封装了旋转视图。
这是问题的图示(帧属性标记为A,和视觉UIView
bounds
被标记为B):
当不旋转
+------------------+
| A == B |
+------------------+
当旋转的
+-----------------+
| A . |
| . . |
| . . |
| . . |
| . B . |
| . . |
| . . |
| . |
+-----------------+
我想捕捉是矩形的界限内的水龙头B
(真实边界UIView
,旋转),但是当他们仅在矩形不是A
(的价值frame
财产UIView
),而不是B
。
我会如何计算给定的分支点是否是真正的界限/帧/旋转的边界之内UIView
? 对此有一个方便的方法? 或者,我需要计算的坐标和维度B
用自己的几何?
(如果是后者,请包括一个建议,以便我们能够做出回答尽可能完整,谢谢!)
你发现了一个基本的绊脚石,每个人都有当他们第一次的框架和边界的工作。
帧是最小的可能的(非旋转)的矩形,其中的视图配合在,考虑到转化。 这意味着,如果你要测试触摸,你可以,只要它是最小的矩形内登录视图四周的可用空间。
对于视觉,想象中的蓝色方块是一个转化UIView
。 视图四周的蓝色边框表示它的框架。 请注意如何,即使视图转换,它的框架仍然未改变,并采用标准的地位。 绿色区域表示,如果是可触摸的区域frame
,而是只传递的bounds
:
边界,而另一方面,代表reciever的关于自身的长方形,考虑到转换,并在视图通过传递范围(一后,所以测试的点-convertPoint:toView:
调用)将正确返回是否没有给出触摸(点)相交的视图。
这里是代码,viewB是目标视图,viewA是包含点源视图。
if(CGRectContainsPoint(viewB.bounds, [viewA convertPoint:point toView:viewB])){
//...
}
我想出了这个答案,因为我想要一个完整的代码响应解释。 如果有人需要的代码,为了完整起见,我这是怎么结束了计算,如果一个视图(containerView)完全包含在另一个视图(View):
-(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);
}