MKAnnotation - 如何在注释气泡上显示按钮

时间:2014-04-26 07:08:04

标签: ios objective-c mapkit

我正在尝试使用地图在其中设置注释,用户想要放置它。

我希望用户触摸他想要放置针脚的屏幕,然后通过点击显示的针脚,他可以被重定向到另一个可以放置细节的视图。

我按照几个教程使按钮出现在标注的右侧,但这不起作用......

这是我的代码:

MAPpin是NSObject文件:

MAPpin.h:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MAPpin : NSObject <MKAnnotation> {

    CLLocationCoordinate2D coordinate;
    NSString *title;
    NSString *subtitle;
}
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end

MAPpin.m:

#import "MAPpin.h"

@implementation MAPpin

@synthesize coordinate,title,subtitle, mapView;


@end

我的视图控制器:

MAPwelcomeViewController.h

#import <UIKit/UIKit.h>
#import <MAPKit/MKAnnotation.h>
#import "MAPAppDelegate.h"
#import "MAPpin.h"

@interface MAPwelcomeViewController : UIViewController <MKMapViewDelegate>
- (IBAction)longpress:(UILongPressGestureRecognizer *)sender;

@property (weak, nonatomic) IBOutlet MKMapView *mapView;

@end

和MAPwelcomeViewController.m:

#import "MAPwelcomeViewController.h"
#import "MAPpin.h"
#import "myAnnotation.h"
#define METERS_PER_MILE 1609.344

@interface MAPwelcomeViewController ()

@end

@implementation MAPwelcomeViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    {
        [super viewDidLoad];
        _mapView.showsUserLocation = YES;

    }
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    //1
    CLLocationCoordinate2D zoomLocation;
    zoomLocation.latitude = 40.740848;
    zoomLocation.longitude= -73.991145;
    // 2
    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.3*METERS_PER_MILE, 0.3*METERS_PER_MILE);
    [self.mapView setRegion:viewRegion animated:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
    [self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];


}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/






#pragma mark -MapView Delegate Methods
//6
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    //7
    if([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    //8
    static NSString *identifier = @"myAnnotation";
    MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    if (!annotationView)
    {
        //9
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        annotationView.pinColor = MKPinAnnotationColorPurple;
        annotationView.animatesDrop = YES;
        annotationView.canShowCallout = YES;
    }else {
        annotationView.annotation = annotation;
    }
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    return annotationView;
}

- (IBAction)longpress:(UILongPressGestureRecognizer *)sender {

    CGPoint point = [sender locationInView:self.mapView];

    CLLocationCoordinate2D loccoord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];


    myAnnotation *ann = [[myAnnotation alloc] initWithCoordinate:loccoord title:@"Test"];
    [self.mapView addAnnotation:ann];

}

@end

所以关注(http://www.codigator.com/tutorials/mapkit-tutorial-for-ios-beginners/“这个链接”)我添加了以下方法:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation

但是当我运行应用程序时,没有按钮显示...你认为我做错了什么?

提前致谢,

问候!

1 个答案:

答案 0 :(得分:0)

最有可能的情况是,地图视图的delegate未设置,因此viewForAnnotation委托方法永远不会被调用,地图视图会创建一个没有标注附件按钮的默认红色图钉。

在故事板中,右键单击地图视图控件并将其delegate插座连接到视图控制器。

或者,在代码中,在viewDidLoad方法中,在设置showsUserLocation之前,以编程方式设置delegate

self.mapView.delegate = self;


<小时/> 一些无关的评论......

一旦出现按钮,为了处理用户点击标注附件,推荐的方法是实现calloutAccessoryControlTapped委托方法。有关示例,请参阅MKAnnotationView Push to View Controller when DetailDesclosure Button is Clicked的答案。

我应该指出的另一个问题是,在创建注释之前,手势处理程序方法不会检查手势识别器state。因此,当用户仍在进行单次长按时,可能会发生多个引脚。要避免这种情况,请在longpress:方法的顶部添加如下所示的检查:

if (sender.state != UIGestureRecognizerStateBegan)
{
    return;
}

另一个不相关的事情是代码是通过执行myAnnotation创建类型myAnnotation alloc的注释,但是您显示的注释类是MAPpin类型。

最后,在MKMapView类中添加MAPpin作为IBOutlet和属性完全是不必要的。你应该把它从那里移除然后才会引起混乱。