Search code examples
objective-cioswarningsmkannotationmkannotationview

MKAnnotationView - MKAnnotation Parameter Warnings


I currently have a map view that is populated with several objects following the MKAnnotation protocol. There is two separate types of objects, stores and competitors. The different objects have different types of data attached to them.

When the mapView is loaded, the program automatically drops all the pins for our stores and competitors onto the map. Each pin uses a custom image. When you zoom out to a larger area, obviously the screen can get quite cluttered. I have looked at filtering objects based on proximity as described in this blog: http://www.fiveminutes.eu/having-fun-with-ios-map-kit-grouping-annotations/

But after discussing it with some coworkers, we decided to try instead to switch our fairly large "square-styled" pins with smaller needle-point pins after the map region was changed to have a latitude or longitude delta greater than 1.0

I have created the methods and implemented the process to achieve switching between the smaller and larger pins as a user zooms in and out, but I cannot seem to get rid of this warning:

Sending "MKAnnotationView *" to parameter of incompatible type 'id<MKAnnotation>'

I know that this means we are probably doing something wrong which could in the future cause problems, so I would like to get it fixed before our v1.1 release in a few days.

The following method is how I test to see if my region has changed beyond the point where I want to change pins. usingLargeIcons is a Boolean value that just keeps keeps us from calling the change method when the icons are already at the desired size.

-(void)mapView:(MKMapView *)mapViewChanged regionDidChangeAnimated:(BOOL)animated
{
    NSLog(@"latitudeDelta = %f",mapViewChanged.region.span.latitudeDelta);
    NSLog(@"longitudeDelta = %f",mapViewChanged.region.span.longitudeDelta);
    //Sanity check on region
    if(mapView.region.span.latitudeDelta < 1.0){
        if(!usingLargeIcons){
            [self transformPinsLarge];
        }
    }else{
        if(usingLargeIcons){
            [self transformPinsSmall];
        }
    }
}

This method as you can see is just calling two transform methods. The methods are almost identical, but have two simple word changes Small and Large. My goal was to take all the pins on the map and dump them into an array, cycle through the array and switch to the smaller pins. I don't understand why we are receiving the warning about our objects not matching up. If I have missed this on another questions here at SO, I apologize, please just point me in the right direction and I'll be on my way. I have Google searched several style questions and haven't found anything to describe this object warning.

The transform methods:

- (void)transformPinsSmall
{
    usingLargeIcons = NO;
    NSArray *allPins = [mapView annotations];
    for (MKAnnotationView *a in allPins) {
        //Gets small UIImage for brand, changes pin image
        [[mapView viewForAnnotation:a] setImage:[self imageForSmallAnnotation:a]];
    }
}

The warning is on the line of code in the for loop. The "imageForSmallAnnotation" method is just returning a UIImage object. Can someone please explain to me how to type cast these images or how to cast my method declaration so that I can remove these errors?

Thanks.


Solution

  • Any chance the error message is actually

    Sending "MKAnnotationView *" to parameter of incompatible type 'id<MKAnnotation>'
    

    ...as opposed to id<MKAnnotationView>?

    If so, then the problem is that [mapView annotations] returns an array of annotations (that is, objects that adopt the MKAnnotation protocol), and your for loop is casting those objects to MKAnnotationView, which then runs into problems. You could try:

    for (id <MKAnnotation> a in allPins) {
    

    ...which would solve the problem where [mapView viewForAnnotation:a] is expecting a to be an object that adopts the MKAnnotation protocol, but is being sent an object that's been cast to MKAnnotationView instead.

    You may also need to make sure your code for [self imageForSmallAnnotation:] is receiving the class of object it expects to receive, if and when you change what a is being cast to.