5

我有一个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属性的值UIView)而不是B

我如何计算给定的点击点是否在旋转的真实边界/框架/边界内UIView?有没有方便的方法?或者我是否需要计算B使用我自己的几何图形的坐标和尺寸?

(如果是后者,请提出建议,以便我们尽可能完整地回答。谢谢!)

4

3 回答 3

11

你会发现每个人第一次为框架和边界工作时都会遇到的一个基本绊脚石。

框架是视图适合的最小可能(非旋转)矩形,考虑到变换。这意味着,如果您要测试触摸,您可以登录视图周围的可用空间,只要它位于尽可能小的矩形内。

对于视觉,想象蓝色方块是一个变形的UIView. 视图周围的蓝色边框代表它的框架。请注意,即使视图已转换,它的框架仍保持未转换并处于标准位置。绿色区域表示如果frame通过而不是可以触摸的区域bounds

框架

另一方面,边界表示接收者相对于自身的矩形,考虑到变换,因此通过传递边界(在-convertPoint:toView:调用之后)测试视图中的点将正确返回给定的触摸(点)是否相交风景。

于 2012-12-25T08:28:08.480 回答
4

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

if(CGRectContainsPoint(viewB.bounds, [viewA convertPoint:point toView:viewB])){
    //...
}
于 2014-02-27T18:40:55.237 回答
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);
}
于 2016-09-01T10:20:24.537 回答