2012-12-25 64 views
4

我有一個UIView,用戶可以點擊UIView來'選擇'或突出顯示它所代表的應用內'東西'。我使用CGRectContainsPoint(thing.frame,tapPoint)來實現此目的,其中thing.frameUIView的幀,而tapPoint是來自UITapGestureRecognizer的分接點。這工作完美。如何在旋轉的UIView中使用CGRectContainsPoint()

..當通過設置transform屬性(具有CGAffineTransform值)來旋轉UIView時除外。當UIView像這樣旋轉時,frame變成封裝旋轉視圖的扁平正方形。

這是問題的圖示(幀屬性被標記爲A,和視覺UIViewbounds被標記爲B):

當不旋轉

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

旋轉時

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

我想c在旋鈕B(旋轉的真實邊界)範圍內的爆破敲擊,但不是當它們僅在矩形Aframe屬性的值UIView)而不是當在B時。

我該如何計算給定的分接點是否在旋轉的UIView的真實邊界/框架/邊界內?有沒有一個方便的方法呢?或者我需要使用我自己的幾何圖形來計算B的座標和尺寸?

(如果是後者,請包括一個建議,以便我們能夠做出回答儘可能完整。謝謝!)

+0

+1的方法問題是格式化。 – iDev

回答

10

你發現了一個基本的絆腳石,每個人都有當他們爲框架的第一個工作,界限。

框架是考慮到轉換,視圖適合的最小可能(非旋轉)矩形。意思是,如果您要測試觸摸,只要在該最小可能的矩形內,您就可以登錄視圖周圍的可用空間。

對於視覺效果,想象藍色方塊是一個變形的UIView。視圖周圍的藍色邊框表示它的框架。注意,即使視圖被轉換,它的框架仍然未被轉換並處於標準位置。綠色區域表示如果frame傳遞,而不是bounds是可觸摸的區域:

frame

界限,而另一方面,代表reciever的矩形相對於本身,考慮到轉換,所以測試在視圖中通過傳遞邊界(在-convertPoint:toView:調用後)中的點將正確返回給定觸摸(點)是否與視圖相交。

+0

這工作完美;我已經在使用邊界的路徑,但'convertPoint:toView:'是關鍵。但是,我仍然不完全理解這種方法的內部工作原理。它是僅僅應用新穎的數學,並使用簡單的幾何學來計算真正的旋轉邊界?或者,這是否與一個負責任的開發人員應該理解的'UIView'做些什麼? – toblerpwn

+2

實際上,當你得到UIView的框架時,框架實際上並不查詢視圖,而是查詢大量其他屬性,並執行一些快速的數學運算來返回結果。界限是對象「框架」的真實表示。 – CodaFi

+0

但是'bounds'仍然顯示爲(0,0,width,height) - 至少它的'description'屬性是。所以這聽起來似乎並不是隱藏在我們可以訪問的某個地方,而是「UIView」可以輕鬆地自行計算的東西。如果我有這個想法,非常高興知道,謝謝。 :) – toblerpwn

2

這裏是代碼,viewB是目標視圖,viewA是包含點的源視圖。

​​
+0

爲我工作:P – zszen

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); 
}