2012-11-08 47 views
3

我一直strunggling對我的項目的問題:CustomAnnotationView一個按鈕

我有一個MapView,我必須表現出以下給出的註解(小(+)是我的按鈕)

what's I have to do

我子類MKAnnotationView和我有CustomAnnotationView.h這樣的:

@interface CustomAnnotationView : MKAnnotationView 

@property (strong, nonatomic) UIImageView *calloutView; 
@property (strong, nonatomic) UIButton *pinButton; 
@property (strong, nonatomic) UIView *annView; 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated; 
- (void)animateCalloutAppearance; 

我CustomAnnotationView.m

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{ 
    [super setSelected:selected animated:animated]; 


    if(selected) 
    { 
     //building my custom animation 
     annView = [[ UIView alloc ] initWithFrame:(CGRectMake(0, 0, 30, 30)) ]; 

     annView.frame =CGRectMake(0, 0, 200, 50); 

     calloutView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"customcallout.png"]]; 


     [calloutView setFrame:CGRectMake(-25, 50, 0, 0)]; 
     [calloutView sizeToFit]; 


     [self animateCalloutAppearance]; 

     //I tried to add a button here but I could't do it like it should be 
     [annView addSubview:calloutView]; 

     [self addSubview:annView]; 

    } 
    else 
    { 
     //Remove your custom view... 

     [annView removeFromSuperview]; 
    } 
} 

- (void)didAddSubview:(UIView *)subview{ 


     if ([[[subview class] description] isEqualToString:@"UICalloutView"]) { 
      for (UIView *subsubView in subview.subviews) { 
       if ([subsubView class] == [UIImageView class]) { 
        UIImageView *imageView = ((UIImageView *)subsubView); 
        [imageView removeFromSuperview]; 
       }else if ([subsubView class] == [UILabel class]) { 
        UILabel *labelView = ((UILabel *)subsubView); 
        [labelView removeFromSuperview]; 
       } 
      } 

    } 
} 


- (void)animateCalloutAppearance { 
    CGFloat scale = 0.001f; 
    calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, -50); 

    [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationCurveEaseOut animations:^{ 
     CGFloat scale = 1.1f; 
     calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, 2); 

    } completion:^(BOOL finished) { 
     [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{ 
      CGFloat scale = 0.95; 
      calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, -2); 

     } completion:^(BOOL finished) { 
      [UIView animateWithDuration:0.075 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{ 
       CGFloat scale = 1.0; 
       calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, 0); 

      } completion:nil]; 
     }]; 
    }]; 
} 

@end 

有了這個我能夠在地圖上顯示我的自定義註釋,但我無法弄清楚如何在其上放置一個按鈕,當然這個按鈕應該能夠像回調響應點擊calloutAccessoryControlTapped:

請任何人有一個工作示例代碼或想法。 謝謝。

回答

4

我在我的CustmAnnotationView.m類中使用- (UIView*)hitTest解決了這個問題。我有標註視圖一個單獨的筆尖,用則hitTest來確定是否的UILabel命名爲directionsButton(從標註筆尖鏈接)被點擊:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
{ 
    if (selected) { 
     calloutVisible = YES; 
     hitTestBuffer = NO; 
     self.calloutView = [[[NSBundle mainBundle] loadNibNamed:@"CalloutView" owner:self options:nil] objectAtIndex:0]; 
     [directionsButton setFont:[UIFont fontWithName:@"DIN-Medium" size:12.0f]]; 
     [calloutView setFrame:CGRectMake(calloutView.frame.origin.x, calloutView.frame.origin.y, 280, calloutView.frame.size.height)];   
     [calloutView setAlpha:0.0f];  
     [self addSubview:calloutView]; 
     [self sendSubviewToBack:calloutView]; 


     [UIView animateWithDuration:0.3f delay:0.0f options:0 animations:^{  
      [calloutView setAlpha:1.0f]; 
     } completion:^(BOOL finished) { 
     }]; 

     [super setSelected:selected animated:animated]; 

    } else { 
     calloutVisible = NO; 

     CGRect newFrame = self.frame; 
     newFrame.size.width = 52; 
     self.frame = newFrame; 

     [UIView animateWithDuration:0.3f delay:0.0f options:0 animations:^{ 
      [calloutView setAlpha:0.0f]; 
     } completion:^(BOOL finished) { 
      [calloutView removeFromSuperview]; 
     }]; 
    } 
} 


- (void)directionsPressed 
{ 
    if ([parent respondsToSelector:@selector(directionsPressed:)]) 
     [parent performSelector:@selector(directionsPressed:) withObject:self.stockist]; 
} 


- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    if (calloutVisible) { 
     CGPoint hitPoint = [calloutView convertPoint:point toView:directionsButton]; 
     if ([calloutView pointInside:hitPoint withEvent:event]) { 
      if (!hitTestBuffer) { 
       [self directionsPressed]; 
       hitTestBuffer = YES; 
      } 
      return [directionsButton hitTest:point withEvent:event]; 
     } else { 
      hitTestBuffer = NO; 
     } 
    } 
    return [super hitTest:point withEvent:event]; 
} 

在我的代碼parent是我現在的VC。這可能不是最簡單的方法,但它在當時起作用。

的標註是這樣的:

callout

一對夫婦布爾calloutVisiblehitTestBuffer確保按鈕只點擊一次,並且只有當可見。

+0

你可以捕捉點擊你的VC能夠顯示方向嗎?如何 ? – moujib

+0

在我的原始文章中,['parent performSelector:@selector(directionsPressed :) withObject:self.stockist];'調用我的視圖控制器('parent')來顯示方向疊加。 –

+0

我接受了你的答案,並給了你賞金點,作爲一個恩惠是否有可能上傳此解決方案的演示項目?它將非常感激。 – moujib

2

爲了嘗試解決您的問題,我玩了一下Apple's WeatherMap example,並提出瞭解決問題的工作方案。

我加入你的代碼到WeatherAnnotationView.m文件(減去動畫代碼),以及最重要的是添加的代碼顯示按鈕,響應觸摸事件:

-(void)annotationButtonClicked{ 
    NSLog(@"** button clicked"); 
} 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{ 
    if(selected) 
    { 
     //building my custom animation 
     annView = [[ UIView alloc ] initWithFrame:(CGRectMake(0, 0, 30, 30)) ]; 

     annView.frame =CGRectMake(0, 0, 200, 50); 

     calloutView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cloudy.png"]]; 


     [calloutView setFrame:CGRectMake(-25, 50, 0, 0)]; 
     [calloutView sizeToFit]; 
     [annView addSubview:calloutView]; 


     /* BUTTON CODE */ 
     UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0,0,20,20)]; 
     button.backgroundColor = [UIColor orangeColor]; 

     [button addTarget:self action:@selector(annotationButtonClicked) forControlEvents:UIControlEventTouchUpInside]; 
     [annView addSubview:button]; 
     /* END Of BUTTON CODE */ 

     [self addSubview:annView]; 

    } 
    else 
    { 
     //Remove your custom view... 
     [annView removeFromSuperview]; 
    } 

} 

您還沒有發佈如何嘗試將按鈕添加到annView,所以我很難理解哪些方法不適用於您的方法。解決這些問題的一種常見方法是一次刪除一段代碼並嘗試運行您的應用程序。對於初學者,嘗試刪除動畫代碼。然後,嘗試刪除calloutView,並僅保留annView和該按鈕,直到您的代碼與按鈕一起工作。之後,請逐一添加您之前刪除的部分(動畫,calloutView),並查看哪一個導致您的按鈕停止功能。

我希望這有助於某種方式。

+0

謝謝你的回答,其實我已經試過了,這個代碼的問題是我需要在其他地方有這個按鈕的回調方法(在我的VC中) – moujib

+0

你有沒有從CustomAnnotationView訪問你的VC。 M&或者,在CustomAnnotationView.m中觸發一個事件並讓VC抓住它? – gardenofwine

+0

我沒有從我的CustomAnnotationView.m類訪問我的VC。我需要點擊VC上的按鈕動作,就像普通的配件標註按鈕一樣。 – moujib