2011-12-27 48 views
8

我目前有一個地圖視圖和一些註解。我有自定義圖像的註釋。我試圖解決的問題是圖像的敏感度。當我試圖拖動它們時,感覺就像我必須觸摸它所關注的確切中心。有沒有辦法讓觸摸邊界更大?如何使MKAnnotationView觸摸敏感?

回答

17

要做到這一點,您需要繼承MKAnnotationView以創建您自己的自定義MKAnnotationView。在您的子類中,覆蓋以下功能:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event 
{ 
    // Return YES if the point is inside an area you want to be touchable 
} 

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event 
{ 
    // Return the deepest view that the point is inside of. 
} 

這允許按下交互式視圖(如按鈕等)。 MKAnnotationView中的默認實現在pointInsidehitTest上並不嚴格,因爲它允許實際上在一個註釋中的按鍵被髮送到不同的註釋。它通過找出離接觸點最近的註釋中心並將事件發送到該註釋來做到這一點,這樣使得緊密連接(重疊)註釋不會阻止彼此被選擇。但是,對於您的情況,如果用戶要選擇並拖動最上面的註釋,您可能想阻止其他註釋,因此上述方法可能是您想要的,否則它會將您設置在正確的路徑上。

編輯: 有人問我在示例實現的hitTest:withEvent:意見 - 這取決於你想實現什麼。原始問題建議在註釋中觸摸和拖動圖像,而在我的情況下,我在註釋內部有一些按鈕,我想要進行交互。這裏是我的代碼:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event 
{ 
    UIView* hitView = [super hitTest:point withEvent:event]; 
    if (hitView != nil) 
    { 
     // ensure that the callout appears above all other views 
     [self.superview bringSubviewToFront:self]; 

     // we tapped inside the callout 
     if (CGRectContainsPoint(self.resultView.callButton.frame, point)) 
     { 
      hitView = self.resultView.callButton; 
     } 
     else if (CGRectContainsPoint(self.resultView.addButton.frame, point)) 
     { 
      hitView = self.resultView.addButton; 
     } 
     else 
     { 
      hitView = self.resultView.viewDetailsButton; 
     } 
     [self preventSelectionChange]; 
    } 
    return hitView; 
} 

正如你可以看到它是相當簡單 - MKAnnotationView實現(稱爲super對我實施的第一行)只返回第一個(最)來看,它並沒有向下穿過鑽查看層次結構以查看觸摸實際在哪個子視圖內。在我的情況下,我只是檢查觸摸是否在三個按鈕之一併返回。在其他情況下,您可能會通過層次結構或更復雜的命中測試進行簡單的基於矩形的向下鑽取,以避免視圖中的透明區域允許觸摸通過這些部分。如果您需要向下鑽取,則可以按照我使用過的方法使用CGRectContainsPoint,但請記住將您的點偏移到您鑽入的每個視圖級別的局部視圖座標中。

preventSelectionChange方法是爲了防止我的自定義註釋變爲被選中,我將它用作來自地圖引腳的可自定義/交互式標註,並且這會保持與選中關聯的引腳而不是允許選擇更改爲此註釋。

+0

您能否實施hitTest方法? – Daniel 2012-04-11 20:33:24

+0

如果我能再次投票您的答案我會!感謝更新。 – Daniel 2012-04-15 00:07:44

+0

你好,請問pointInside:withEvent:?這是您建議實施CGRectContainsPoint的地方嗎? – Daniel 2012-04-16 14:00:14

0

我實現以下方式

  1. 創建處理觸摸
  2. 創建的UIImage類的子類手勢識別類的子類類似的東西,這個類使用識別器類來處理你的手勢
  3. 在註釋中使用此

手勢識別器子類會處理你的手勢,如果你在任何IMA點執行它們GE。這應該對你有所幫助。

保持我們更新了這個解決方案是否曾爲ü...

1

你繼承MKAnnotationView還是你改變只是設置它的圖像屬性?

下面是設置圖像屬性的文檔。

討論: 將新圖像分配給此屬性還會更改視圖框架的大小,使其與新圖像的寬度和高度相匹配。視圖框架的位置不會改變。

檢查註釋視圖的框架大小,這是您的對象可以接受觸摸的位置。

0

@jhabbott解決方案從來沒有爲我工作,正如我所說here

我有一個圖像和一個並排的標籤。該圖像是通過設置annotationview image屬性示出,並通過添加UILabel

標籤我重定向func point(inside:with:)方法將UILabel一個(其包括在所述圖像區域)和hitTest並返回完全相同的視圖我是否點擊了標籤或圖像。但標籤上單擊不產生任何回調...

最後,我結束了通過擴大MKAnnotationView框架附上標籤+圖像,我設置annotationView.imagenil,我創造了我的自定義UIImageView

因爲我想在圖像中間的錨點,我必須設置一個自定義的:

self.frame = CGRect(x: 0, y: 0, width: 
self.myLabel.frame.width, height: self.myLabel.frame.height) 
self.centerOffset = CGPoint(x: self.frame.width/2, y: self.myImageView.frame.height/2) 

然後我刪除point(inside:with:)hitTest(point:with:)將覆蓋什麼也沒做。

而現在,第一次,我的標註視圖是完全反應。