如何从通过 MKAnnotationView 添加的按钮获取单击事件

发布于 2024-11-28 01:07:13 字数 844 浏览 0 评论 0原文

任何人都知道是否有办法从添加到 MKAnnotationViewbutton 获取点击事件,此 button 用作标签,只是为了显示map 上每个 pin 的名称,现在我成功地在 pin 时显示自定义 view (其中包含图像、文本......) > 被点击所以我需要在按钮时做同样的事情(标签)被单击。

感谢您提供的任何建议。

MKAnnotationViewbutton 的代码:

UIButton * pinButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 140, 28)];
[pinButton.titleLabel setTextColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1]]; 
[pinButton setCenter:CGPointMake(pinAnnotationView.center.x + 70, pinAnnotationView.center.y + 10)]; 
[pinButton addTarget:self action:@selector(pinLabelClicked) forControlEvents:UIControlEventTouchUpInside]; 
[pinAnnotationView addSubView:pinButton]; 
[pinButton setUserInteractionEnabled:YES];

Anyone know if there's a way to get click event from a button that is added to MKAnnotationView, this button is used as label just to display the name of each pin on the map , now I successd to show a custom view (which contains image, text ....) when the pin is clicked so i need to do the same thing when the button (label) is clicked.

Thanks for any advice you can provide.

code for button in MKAnnotationView:

UIButton * pinButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 140, 28)];
[pinButton.titleLabel setTextColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1]]; 
[pinButton setCenter:CGPointMake(pinAnnotationView.center.x + 70, pinAnnotationView.center.y + 10)]; 
[pinButton addTarget:self action:@selector(pinLabelClicked) forControlEvents:UIControlEventTouchUpInside]; 
[pinAnnotationView addSubView:pinButton]; 
[pinButton setUserInteractionEnabled:YES];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自此以后,行同陌路 2024-12-05 01:07:13

标准 UI 方法是使用标注视图并添加一个附件按钮,如 progrmr 显示的那样。

但是,如果您必须直接向 MKAnnotationView 添加按钮,则您的方法的问题在于 MKPinAnnotationView 的默认框架(无法轻易更改)是小于您要添加的按钮,因此大多数按钮不会响应触摸,即使您切换到使用 MKAnnotationView 并增加框架大小,MKMapView 也会防止按钮获取任何触摸。

您需要做的是将 UITapGestureRecognizer 添加到按钮(使用手势处理程序的操作方法而不是按钮上的 addTarget)并将按钮添加到普通的 MKAnnotationView 使用适当的帧大小而不是 MKPinAnnotationView

示例:

- (MKAnnotationView *)mapView:(MKMapView *)mapView 
        viewForAnnotation:(id<MKAnnotation>)annotation
{
    MKAnnotationView *annView = (MKAnnotationView *)[mapView 
            dequeueReusableAnnotationViewWithIdentifier: @"pin"];
    if (annView == nil)
    {
        annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation 
                      reuseIdentifier:@"pin"] autorelease];

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

        UIButton *pinButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        pinButton.frame = CGRectMake(0, 0, 140, 28);
        pinButton.tag = 10;

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] 
            initWithTarget:self action:@selector(handlePinButtonTap:)];
        tap.numberOfTapsRequired = 1;
        [pinButton addGestureRecognizer:tap];
        [tap release];

        [annView addSubview:pinButton]; 
    }

    annView.annotation = annotation;

    UIButton *pb = (UIButton *)[annView viewWithTag:10];
    [pb setTitle:annotation.title forState:UIControlStateNormal];

    return annView;
}

- (void) handlePinButtonTap:(UITapGestureRecognizer *)gestureRecognizer 
{
    UIButton *btn = (UIButton *) gestureRecognizer.view;
    MKAnnotationView *av = (MKAnnotationView *)[btn superview];
    id<MKAnnotation> ann = av.annotation;
    NSLog(@"handlePinButtonTap: ann.title=%@", ann.title);
}

请注意,这将阻止触发地图视图的 didSelectAnnotationView 委托方法。如果您需要触发该方法(除了按钮的手势处理程序方法之外),请添加以下内容:

//in the view controller's interface:
@interface YourVC : UIViewController <UIGestureRecognizerDelegate>

//where the UITapGestureRecognizer is created:
tap.delegate = self;

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
        shouldRecognizeSimultaneouslyWithGestureRecognizer
            :(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

The standard UI approach is to use the callout view and add an accessory button as progrmr shows.

However, if you must add a button directly to the MKAnnotationView, the problems with your approach are that the MKPinAnnotationView's default frame (which can't easily be changed) is smaller than the button you're adding so most of the button will not respond to touches and even if you switch to using an MKAnnotationView and increase the frame size, the MKMapView will prevent the button from getting any touches.

What you'll need to do is add a UITapGestureRecognizer to the button (use the gesture handler's action method instead of an addTarget on the button) and add the button to a plain MKAnnotationView with an appropriate frame size instead of an MKPinAnnotationView.

Example:

- (MKAnnotationView *)mapView:(MKMapView *)mapView 
        viewForAnnotation:(id<MKAnnotation>)annotation
{
    MKAnnotationView *annView = (MKAnnotationView *)[mapView 
            dequeueReusableAnnotationViewWithIdentifier: @"pin"];
    if (annView == nil)
    {
        annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation 
                      reuseIdentifier:@"pin"] autorelease];

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

        UIButton *pinButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        pinButton.frame = CGRectMake(0, 0, 140, 28);
        pinButton.tag = 10;

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] 
            initWithTarget:self action:@selector(handlePinButtonTap:)];
        tap.numberOfTapsRequired = 1;
        [pinButton addGestureRecognizer:tap];
        [tap release];

        [annView addSubview:pinButton]; 
    }

    annView.annotation = annotation;

    UIButton *pb = (UIButton *)[annView viewWithTag:10];
    [pb setTitle:annotation.title forState:UIControlStateNormal];

    return annView;
}

- (void) handlePinButtonTap:(UITapGestureRecognizer *)gestureRecognizer 
{
    UIButton *btn = (UIButton *) gestureRecognizer.view;
    MKAnnotationView *av = (MKAnnotationView *)[btn superview];
    id<MKAnnotation> ann = av.annotation;
    NSLog(@"handlePinButtonTap: ann.title=%@", ann.title);
}

Note that this will prevent the map view's didSelectAnnotationView delegate method from firing. If you need that method to fire (in addition to the button's gesture handler method), then add the following:

//in the view controller's interface:
@interface YourVC : UIViewController <UIGestureRecognizerDelegate>

//where the UITapGestureRecognizer is created:
tap.delegate = self;

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
        shouldRecognizeSimultaneouslyWithGestureRecognizer
            :(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
半枫 2024-12-05 01:07:13

我使用以下代码向标注视图(在我的应用程序中)添加了一个按钮(为了清晰起见,进行了缩减):

-(MKAnnotationView *)mapView:(MKMapView *)map 
        viewForAnnotation:(StationItem*)annotation
{
    static NSString *AnnotationViewID = @"stationViewId";

    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;  // use default user location view
    }

    MKPinAnnotationView *annotationView = 
        (MKPinAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

    if (annotationView == nil) {
        // if an existing pin view was not available, create one
        annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];

        // add rightAccessoryView
        UIButton* aButton = [UIButton buttonWithFrame:CGRectMake(0, 0, 75, 30)];
        [aButton setTitle:@"Directions" forState:UIControlStateNormal];
        annotationView.rightCalloutAccessoryView = aButton;
    }

    annotationView.annotation = annotation;
    annotationView.canShowCallout = YES;
    annotationView.animatesDrop   = NO;

    return annotationView;
}

执行此操作后,您需要实现 MKMapViewDelegate 以在点击按钮时处理对委托的回调:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

I added a button to the callout view (in my app) using this code (reduced for clarity):

-(MKAnnotationView *)mapView:(MKMapView *)map 
        viewForAnnotation:(StationItem*)annotation
{
    static NSString *AnnotationViewID = @"stationViewId";

    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;  // use default user location view
    }

    MKPinAnnotationView *annotationView = 
        (MKPinAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

    if (annotationView == nil) {
        // if an existing pin view was not available, create one
        annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];

        // add rightAccessoryView
        UIButton* aButton = [UIButton buttonWithFrame:CGRectMake(0, 0, 75, 30)];
        [aButton setTitle:@"Directions" forState:UIControlStateNormal];
        annotationView.rightCalloutAccessoryView = aButton;
    }

    annotationView.annotation = annotation;
    annotationView.canShowCallout = YES;
    annotationView.animatesDrop   = NO;

    return annotationView;
}

After doing this you need to implement the MKMapViewDelegate to handle callback to the delegate when the button is tapped:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
陌上芳菲 2024-12-05 01:07:13

尝试将触摸传递给子视图:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 [pinButton touchesEnded:touches withEvent:event];
}

我很惊讶你有问题,但如果你的buttonView在前面?尝试确保它是:
[self BringSubviewToFront:pinButton];

try passing the touches to the subview:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 [pinButton touchesEnded:touches withEvent:event];
}

I'm surprised you have a problem though if your buttonView is in front? try making sure it is:
[self bringSubviewToFront:pinButton];

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文