Adding a custom annotation to a MKMapview

前端 未结 1 629
礼貌的吻别
礼貌的吻别 2021-01-28 03:00

I am trying to add annotations to a MKMapView

I have created a class CustomMapPin which conforms to the MKAnnotation protocol

相关标签:
1条回答
  • 2021-01-28 03:27

    In viewForAnnotation, CustomMapAnnotationView is never actually alloc+inited (the dequeueReusableAnnotationViewWithIdentifier does not do this).

    If viewForAnnotation is even getting called, it must be returning nil which means the map view must be putting a red pin somewhere (and if the delegate method isn't getting called, then again the map view will default to a red pin). Log the coordinates where the annotation is being added and look there.

    A corrected viewForAnnotation might look like this:

    -(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;
    }
    

    Some other issues with the code:

    1. In viewWillAppear, code is retrieving the location immediately after calling startUpdatingLocation. This is not guaranteed to work every time and even if it does "work", you will most likely be getting an old, cached location. When it doesn't work, the annotation will either end up at 0,0 (Atlantic Ocean) or app will crash due to invalid coordinates. It's much better to read the location in the didUpdateLocations delegate method. In viewWillAppear, call startUpdatingLocation and then in didUpdateLocations, if the accuracy and age of the location is adequate for you, call stopUpdatingLocation and then use the location (create and add the annotation, etc).
    2. In CustomMapAnnotationView, annotationImage object is created and added but its image property is never set. The annotationImage is actually never really used for anything.
    3. The whole CustomMapAnnotationView class is unnecessary for your purpose . In viewForAnnotation, code is setting the image property on the CustomMapAnnotationView (instead of using annotationImage). This image property is inherited from MKAnnotationView. The built-in, basic MKAnnotationView class is all you need for what you're doing. It already has an image property and it automatically displays it for you (you don't need to create your own UIImageView).
    0 讨论(0)
提交回复
热议问题