3

我一直在为我的项目中的一个问题而苦恼:

我有一个 mapView,我必须显示下面的注释(小 (+) 是我的按钮)

我该怎么办

我已经将 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

2 回答 2

4

- (UIView*)hitTest我在CustmAnnotationView.m课堂上解决了这个问题。我有一个单独的用于标注视图的笔尖,并使用 hittest 来确定是否directionsButton单击了命名的 UILabel(从标注笔尖链接):

- (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。这可能不是最简洁的方式,但它在当时有效。

标注如下所示:

大喊

几个布尔值calloutVisible,并hitTestBuffer确保按钮只能点击一次且仅在可见时才可点击。

于 2012-11-14T14:27:36.097 回答
2

为了尝试解决您的问题,我使用了Apple 的 WeatherMap 示例,并为您的问题提出了一个可行的解决方案。

我将您的代码添加到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),看看是哪一个导致您的按钮停止功能。

我希望这会有所帮助。

于 2012-11-12T15:44:05.177 回答