如何使用CGRectContainsPoint()与旋转的UIView(How to use CGR

2019-08-04 15:47发布

我有一个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用自己的几何?

(如果是后者,请包括一个建议,以便我们能够做出回答尽可能完整,谢谢!)

Answer 1:

你发现了一个基本的绊脚石,每个人都有当他们第一次的框架和边界的工作。

帧是最小的可能的(非旋转)的矩形,其中的视图配合在,考虑到转化。 这意味着,如果你要测试触摸,你可以,只要它是最小的矩形内登录视图四周的可用空间。

对于视觉,想象中的蓝色方块是一个转化UIView 。 视图四周的蓝色边框表示它的框架。 请注意如何,即使视图转换,它的框架仍然未改变,并采用标准的地位。 绿色区域表示,如果是可触摸的区域frame ,而是只传递的bounds

边界,而另一方面,代表reciever的关于自身的长方形,考虑到转换,并在视图通过传递范围(一后,所以测试的点-convertPoint:toView:调用)将正确返回是否没有给出触摸(点)相交的视图。



Answer 2:

这里是代码,viewB是目标视图,viewA是包含点源视图。

if(CGRectContainsPoint(viewB.bounds, [viewA convertPoint:point toView:viewB])){
    //...
}


Answer 3:

我想出了这个答案,因为我想要一个完整的代码响应解释。 如果有人需要的代码,为了完整起见,我这是怎么结束了计算,如果一个视图(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);
}


文章来源: How to use CGRectContainsPoint() with rotated UIView