如何在旋转的UIView中使用CGRectContainsPoint()

tob*_*pwn 5 objective-c rotation uiview cgaffinetransform ios

我有一个UIView,用户可以点击UIView"选择"或突出显示它所代表的应用内"事物".我CGRectContainsPoint(thing.frame,tapPoint)用来实现这个,thing.frame它的框架在哪里UIView,并且tapPoint是从a的分接点UITapGestureRecognizer.这很完美.

..except UIView通过设置transform属性(带有CGAffineTransform值)旋转.当UIView像这样旋转时,它frame变成一个封闭旋转视图的扁平方形.

以下是问题的示意图(框架属性标记为A,视觉UIView bounds标记为B):

不旋转时

+------------------+
|      A == B      |
+------------------+
Run Code Online (Sandbox Code Playgroud)

旋转时

+-----------------+
|  A        .     |
|         .   .   |
|       .       . |
|     .       .   |
|   .    B  .     |
| .       .       |
|   .   .         |
|     .           |
+-----------------+
Run Code Online (Sandbox Code Playgroud)

我想捕获在rect的范围内的抽头B(UIView旋转的真实边界),但是当它们仅在rect A(frame属性的值UIView)内时,不是B.

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

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

Cod*_*aFi 11

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

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

对于视觉,想象蓝色方块是一个转换UIView.视图周围的蓝色边框表示它的框架.注意,即使视图被转换,它的帧仍然是未转换的并处于标准位置.绿色区域代表frame传递的区域,如果传递而不是bounds:

帧

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

  • 实际上,当你获得UIView的框架时,框架实际上并不查询视图,而是查询大量其他属性并进行一些快速数学运算以返回结果.边界是对象"框架"的真实表示. (2认同)
  • @toblerpwn视图的`bounds`位于视图自己的坐标系中,而不是其父坐标系.旋转视图时,也会旋转其坐标系.视图的框架实际上是它的图层框架,图层根据它的`position`,`bounds.size`,`anchorPoint`和`transform`计算它的框架. (2认同)