2015-02-24 105 views
0

我想註釋添加到MKMapView添加自定義註釋到的MKMapView

我創建了一個類CustomMapPin這符合MKAnnotation協議

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

@interface CustomMapPin : NSObject <MKAnnotation> { 

    CLLocationCoordinate2D coordinate; 
    NSString *title; 
    NSString *subtitle; 
} 

@property(nonatomic, assign) CLLocationCoordinate2D coordinate; 
@property(nonatomic, copy) NSString *title; 
@property(nonatomic, copy) NSString *subtitle; 
@property(nonatomic, strong) NSString *type; // this is to differentiate between the different annotations on the map 

@end 

我創建了一個類CustomMapAnnotationView這是的一個子類MKAnnotationView

CustomMapAnnotationView.h

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

@interface CustomMapAnnotationView : MKAnnotationView 
@property (nonatomic, strong) UIImageView *annotationImage; 
@end 

CustomMapAnnotationView.m

#import "CustomMapAnnotationView.h" 

@implementation CustomMapAnnotationView 

-(id) initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; 

    if (self) { 
     self.frame = CGRectMake(0, 0, 28, 40); 
     self.backgroundColor = [UIColor clearColor]; 

     self.annotationImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 40)]; 
     self.annotationImage.contentMode = UIViewContentModeScaleAspectFit; 
     [self addSubview:self.annotationImage]; 

    } 
    return self; 
} 

@end 

我加入內部FindMechanicViewController定製銷,它們是一個CLLocationManagerDelegateMKMapViewDelegate

的代碼片段是:

-(void) viewWillAppear:(BOOL)animated { 
    [self.locationManager startUpdatingLocation]; 
    self.currentLocation = [self.locationManager location]; 

    // Set the region of the map 
    MKCoordinateSpan mapViewSpan = MKCoordinateSpanMake(0.01, 0.01); 
    MKCoordinateRegion mapRegion = MKCoordinateRegionMake(self.currentLocation.coordinate, mapViewSpan); 
    [self.mapView setRegion:mapRegion]; 

    // Add custom pin showing user location 
    CustomMapPin *annotation = [[CustomMapPin alloc] init]; 
    annotation.title = @"Current Location"; 
    annotation.coordinate = self.currentLocation.coordinate; 
    annotation.type = @"user location"; 
    [self.mapView addAnnotation:annotation]; 
} 

而委託方法

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { 
    static NSString *reuseId = @"CustomMapPin"; 
    CustomMapAnnotationView *annotationView = (CustomMapAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:reuseId]; 

    if ([annotation isKindOfClass:[CustomMapPin class]]) { 
     CustomMapPin *customAnnotation = (CustomMapPin *)annotation; 

     if ([customAnnotation.type isEqualToString:@"user location"]) { 
      [annotationView setAnnotation:customAnnotation]; 
      [annotationView setImage:[UIImage imageNamed:@"pin_user"]]; 
      [annotationView setCanShowCallout:YES]; 
     } 

    } 
    return annotationView; 
} 

這不會在地圖上顯示任何東西。我該如何解決 ?

+1

該代碼有幾個問題,但一個很大的問題是,在viewForAnnotation中,CustomMapAnnotationView從來沒有真正的alloc + inited(dequeueReusableAnnotationViewWithIdentifier沒有這樣做)。如果viewForAnnotation甚至被調用,它必須返回nil,這意味着地圖視圖必須放置一個紅色的針_somewhere_。記錄添加註釋的座標並在那裏查看。 – Anna 2015-02-24 19:55:39

+0

工作。如果它是nil,我添加了另一行來初始化annotationView。 – 2015-02-24 20:38:13

+0

該代碼還有哪些其他問題? – 2015-02-24 20:39:27

回答

5

viewForAnnotation,CustomMapAnnotationView永遠不會實際分配+引用(dequeueReusableAnnotationViewWithIdentifier不這樣做)。

如果viewForAnnotation甚至獲取調用,必須返回nil這意味着地圖視圖,必須將紅色的大頭針的地方(如果委託方法沒有得到所謂的,然後再在地圖視圖將默認爲紅色銷)。記錄添加註釋的座標並在那裏查看。

一個修正viewForAnnotation可能是這樣的:

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { 
    if ([annotation isKindOfClass:[CustomMapPin class]]) { 
     static NSString *reuseId = @"CustomMapPin"; 

     CustomMapAnnotationView *annotationView = (CustomMapAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:reuseId]; 
     if (!annotationView) { 
      annotationView = [[CustomMapAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId]; 
      [annotationView setCanShowCallout:YES]; 
     } 

     CustomMapPin *customAnnotation = (CustomMapPin *)annotation; 

     //view's annotation should be set regardless of "type" 
     [annotationView setAnnotation:customAnnotation]; 

     if ([customAnnotation.type isEqualToString:@"user location"]) { 
      [annotationView setImage:[UIImage imageNamed:@"pin_user"]]; 
     } 
     else { 
      //If it's not a "user location", then set image 
      //to something else otherwise image will either be nil 
      //or it will show some other annotation's image... 
      [annotationView setImage:[UIImage imageNamed:@"pin_other"]]; 
     } 

     return annotationView; 
    } 

    return nil; 
} 

其他一些問題與代碼:

  1. viewWillAppear,代碼調用startUpdatingLocation後立即檢索位置。這並不保證每次都能正常工作,即使它「工作」,你也很可能會得到一箇舊的,緩存的位置。當它不起作用時,註釋將以0,0(大西洋)結束,否則應用程序將因無效座標而崩潰。閱讀didUpdateLocations委託方法中的位置要好得多。在viewWillAppear中,請撥打startUpdatingLocation,然後撥打didUpdateLocations,如果位置的準確性和年齡足夠適合您,請撥打stopUpdatingLocation,然後使用該位置(創建並添加註釋等)。
  2. CustomMapAnnotationView,annotationImage對象被創建和添加,但其image屬性從未設置。 annotationImage實際上從來沒有真正用於任何事情。
  3. 整個CustomMapAnnotationView類是不必要的爲您的目的。在viewForAnnotation中,代碼將image屬性設置爲CustomMapAnnotationView(而不是使用annotationImage)。這image財產繼承MKAnnotationView。內置的,基本的MKAnnotationView課程是你所需要的。它已經有一個image屬性,它會自動顯示給你(你不需要創建你自己的UIImageView)。
+0

那很完美。謝謝 – 2015-02-25 00:46:42