Is there any method to reset the queue used in dequeueReusableAnnotationViewWithIdentifier?

谁都会走 提交于 2019-12-11 18:41:54

问题


I add custom annotation in a mapview. Based on the internal model of the app the annotations can change color and title (although position may not change). I am using dequeueReusableAnnotationViewWithIdentifierin the method

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

The strange thing is that when the model changes the annotations are "refreshed" to use the correct title and color (I just use removeAnnotations: and add the new ones), but later when playing with the map some old annotations with wrong color are dequeued. I use a different identifier each time the model changes.

here is the code:

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation{
    // in case it's the user location, we already have an annotation, so just return nil
    if ([annotation isKindOfClass:[MKUserLocation class]]){
        return nil;
    }
    if ([annotation isKindOfClass:[APGSAnnotation class]]){
        APGSAnnotation *gsn = (APGSAnnotation*) annotation;
        NSString *GSAnnotationIdentifier = [NSString stringWithFormat:@"gid_%lu_%@", (unsigned long)gsn.gs.gID, self.car.energyType];

        MKAnnotationView *markerView = [theMapView dequeueReusableAnnotationViewWithIdentifier:GSAnnotationIdentifier]; 
        if (markerView == nil) {
            MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation                                                                            reuseIdentifier:GSAnnotationIdentifier];
            annotationView.canShowCallout = YES;
            annotationView.image = [self customizeAnnotationImage:gsn.gs];
            annotationView.opaque = NO;

            UIImageView *sfIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:gsn.logo]];
            annotationView.leftCalloutAccessoryView = sfIconView;

            // http://stackoverflow.com/questions/8165262/mkannotation-image-offset-with-custom-pin-image
            annotationView.centerOffset = CGPointMake(0,-annotationView.image.size.height/2);


            UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            [rightButton addTarget:nil action:nil forControlEvents:UIControlEventTouchUpInside];
            annotationView.rightCalloutAccessoryView = rightButton;

            return annotationView;
        }else{
            markerView.annotation = annotation;
            return markerView;
        }
    }
    return nil;
}

and the customize method

- (UIImage*)customizeAnnotationImage:(APGS*)gs{
    UIImage *markerImage;

    if (gs.gID == self.best.gID) {
        markerImage = [UIImage imageNamed:@"marker_red.png"];
    }else if (gs.type == k1){
        markerImage = [UIImage imageNamed:@"marker_blue.png"];
    }else if (gs.type == k2){
        markerImage = [UIImage imageNamed:@"marker_green.png"];
    }else if (gs.type == k3){
        markerImage = [UIImage imageNamed:@"marker_purple.png"];
    }else if (gs.type == k4){
        markerImage = [UIImage imageNamed:@"marker_brown.png"];
    }
    UIImage *logoImage = [UIImage imageNamed:gs.logo];
    // size the flag down to the appropriate size
    CGRect resizeRect;
    resizeRect.size = markerImage.size;
    CGSize maxSize = CGRectInset(self.view.bounds, kAnnotationPadding, kAnnotationPadding).size;

    maxSize.height -= self.navigationController.navigationBar.frame.size.height + kCallOutHeight;

    if (resizeRect.size.width > maxSize.width)
        resizeRect.size = CGSizeMake(maxSize.width, resizeRect.size.height / resizeRect.size.width * maxSize.width);

    if (resizeRect.size.height > maxSize.height)
        resizeRect.size = CGSizeMake(resizeRect.size.width / resizeRect.size.height * maxSize.height, maxSize.height);

    resizeRect.origin = CGPointMake(0.0, 0.0);
    float initialWidth = resizeRect.size.width;

    UIGraphicsBeginImageContextWithOptions(resizeRect.size, NO, 0.0f);
    [markerImage drawInRect:resizeRect];
    resizeRect.size.width = resizeRect.size.width/2;
    resizeRect.size.height = resizeRect.size.height/2;

    resizeRect.origin.x = resizeRect.origin.x + (initialWidth - resizeRect.size.width)/2;
    resizeRect.origin.y = resizeRect.origin.y + kLogoHeightPadding;

    [logoImage drawInRect:resizeRect];


    // Create string drawing context
    UIFont *font = [UIFont fontWithName:@"DBLCDTempBlack" size:11.2];
    NSString * num = [NSString stringWithFormat:@"%4.3f",[gs getL]];
    NSDictionary *textAttributes = @{NSFontAttributeName: font,
                                     NSForegroundColorAttributeName: [UIColor whiteColor]};

    CGSize textSize = [num sizeWithAttributes:textAttributes];

    NSStringDrawingContext *drawingContext = [[NSStringDrawingContext alloc] init];

    //adjust center
    if (resizeRect.size.width - textSize.width > 0) {
        resizeRect.origin.x += (resizeRect.size.width - textSize.width)/2;
    }else{
        resizeRect.origin.x -= (resizeRect.size.width - textSize.width)/2;
    }

    resizeRect.origin.y -= kTextPadding;
    [num drawWithRect:resizeRect
              options:NSStringDrawingUsesLineFragmentOrigin
           attributes:textAttributes
              context:drawingContext];

    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resizedImage;
}

Based on car type the annotations should change color.


回答1:


Based on the title, the answer is NO :)

Normally you would dequeue the view and reset all relevant properties of the view

workaround:

What you can consider is: if the views would change too much, you could switch to a different reusingIdentifier, thereby switching the queue and 'circumventing' the cached views



来源:https://stackoverflow.com/questions/25591038/is-there-any-method-to-reset-the-queue-used-in-dequeuereusableannotationviewwith

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!