5

私はを持ってUIViewおり、ユーザーはをタップしUIViewて「選択」するか、それが表すアプリ内の「もの」を強調表示することができます。私はCGRectContainsPoint(thing.frame,tapPoint)これを達成するために使用します。ここthing.frameで、はのフレームでありUIViewtapPointはからのタップポイントUITapGestureRecognizerです。これは完璧に機能します。

..プロパティを(値を使用して)UIView設定して回転する場合を除きます。このように回転すると、回転したビューをカプセル化した平らな正方形になります。transformCGAffineTransformUIViewframe

問題の図を次に示します(フレームプロパティにはAのラベルが付けられ、ビジュアルUIView boundsにはBのラベルが付けられています)。

回転していないとき

+------------------+
|      A == B      |
+------------------+

回転したとき

+-----------------+
|  A        .     |
|         .   .   |
|       .       . |
|     .       .   |
|   .    B  .     |
| .       .       |
|   .   .         |
|     .           |
+-----------------+

Brectの境界(の真の境界、rotated)内にあるタップをキャプチャしたいのですが、 rect(のプロパティの値)UIView内にあり、。ではない場合はキャプチャしません。AframeUIViewB

与えられたタップポイントが回転した真の境界/フレーム/境界内にあるかどうかをどのように計算できますかUIView?これには便利な方法がありますか?Bまたは、自分のジオメトリを使用して座標と寸法を計算する必要がありますか?

(後者の場合は、可能な限り完全な回答ができるように提案を含めてください。ありがとうございます!)

4

3 に答える 3

11

あなたは、フレームとバウンドで最初に作業するときに誰もが持っている1つの基本的な障害を発見しています。

フレームは、変換を考慮して、ビューが収まる最小の(回転しない)長方形です。つまり、タッチをテストする場合、ビューが可能な限り最小の長方形内にある限り、ビューの周囲の使用可能なスペースにログインできます。

視覚的には、青い正方形が変形されていると想像してください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)が別のビュー(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);
}
于 2016-09-01T10:20:24.537 に答える