【问题标题】:Problems with MapView Pin Annotation - Pin loses color when map is zoomed/panned/region changesMapView Pin Annotation 的问题 - 当地图缩放/平移/区域更改时,Pin 会失去颜色
【发布时间】:2012-11-08 14:42:48
【问题描述】:

我有一个显示现金点位置的地图视图。注释被删除,并且可以单击标注以转到包含有关该位置的更多详细信息的页面。现金点有两类,免费和付费,免费现金点针是绿色的,另一个是红色的。当别针掉落时,它们是正确的颜色。一切正常,直到我放大到用户位置或地图的其他区域,然后当我回到图钉时,它们已经失去了颜色格式并且都是原始的红色。

我认为这与地图在下载图块时重新加载以及未正确重新加载图钉有关,尽管我可能是错的。

任何帮助将不胜感激。

这是我的代码:

#import "CashPointMapViewController.h"
#import "PinDrop.h"
#import "CashPointDetailViewController.h"

@implementation CashPointMapViewController
@synthesize app, theCashList, mapview, ann, count, myArray, pinColor;

- (IBAction) getlocation { 

    MKCoordinateRegion region;
    region.center = self.mapview.userLocation.coordinate;
    region.span.longitudeDelta = 0.01f;
    region.span.longitudeDelta = 0.01f;
    [mapview setRegion:region animated:YES];
}

- (void)viewDidLoad {

    [super viewDidLoad];

    mapview.showsUserLocation = YES;

    [mapview setMapType:MKMapTypeStandard];
    [mapview setZoomEnabled:YES];
    [mapview setScrollEnabled:YES];

    MKCoordinateRegion region = { {0.0, 0.0 }, {0.0, 0.0 } };
    region.center.latitude = 53.801279;
    region.center.longitude = -1.548567;
    region.span.longitudeDelta = 0.3f;
    region.span.longitudeDelta = 0.3f;
    [mapview setRegion:region animated:YES];

    app = [[UIApplication sharedApplication]delegate];

    UIImage *locate = [UIImage imageNamed:@"location arrow white.png"];

    UIBarButtonItem *userlocatebutton = [[UIBarButtonItem alloc] initWithImage:locate     style:UIBarButtonItemStylePlain target:self action:@selector(getlocation)];

    self.navigationItem.rightBarButtonItem = userlocatebutton;

    [self performSelectorInBackground:@selector(annloop) withObject:self];

}


-(void) annloop {

    int i;
    for (i=0; i<=count-1; i = i+1) {
    theCashList = [myArray objectAtIndex:i];

    NSString *trimlat = [theCashList.lat stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSString *trimlon = [theCashList.lon stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    double latdouble = [trimlat doubleValue];
    double londouble = [trimlon doubleValue];

    CLLocationCoordinate2D coord = {(latdouble),(londouble)};

    ann = [[PinDrop alloc] init];

    ann.index = i;

    ann.title = [theCashList.name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    NSString *street = [theCashList.street stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSString *town = [theCashList.town stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSString *postcode = [theCashList.postcode stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    NSString *address = [[NSString alloc] initWithFormat:@"%@, %@, %@", street, town, postcode];

    ann.subtitle = address;
    ann.coordinate = coord;

    NSString *trimprice = [theCashList.price stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    if ([trimprice isEqualToString:@"Free"])
    {
        ann.price = 1;
    }
    else
    {
        ann.price = 0;
    }
    [mapview performSelectorOnMainThread:@selector(addAnnotation:) withObject:ann waitUntilDone:YES];
    }
}


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

    if ([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

    MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc]initWithAnnotation:ann reuseIdentifier:@"current"];
    mypin.backgroundColor = [UIColor clearColor];
    UIButton *goToDetail = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    mypin.rightCalloutAccessoryView = goToDetail;
    mypin.draggable = NO;
    mypin.animatesDrop = TRUE;
    mypin.canShowCallout = YES;


    if (ann.price == 1)
    {
        mypin.pinColor = MKPinAnnotationColorGreen;
    }
    else
    {
        mypin.pinColor = MKPinAnnotationColorRed;
    }
    return mypin;
    }


- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control {

   PinDrop *annView = view.annotation;
    CashPointDetailViewController *detailView = [[CashPointDetailViewController alloc]init];
    theCashList = [myArray objectAtIndex:annView.index];
    detailView.theCashList = theCashList;
    [self.navigationController pushViewController:detailView animated:YES];

}


- (void)viewDidUnload {

    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:   (UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

编辑:如果有帮助,这是我的 .h。

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "CashPointList.h"
#import <MapKit/MapKit.h>
#import "PinDrop.h"

@interface CashPointMapViewController : UIViewController  {

    MKMapView *mapview;
    PinDrop *ann;
}

    @property (nonatomic, retain) AppDelegate *app;
    @property (nonatomic, retain) CashPointList *theCashList;
    @property (nonatomic, retain) PinDrop *ann;
    @property (nonatomic, retain) IBOutlet MKMapView *mapview;
    @property (nonatomic, readwrite) int count;
    @property (nonatomic, retain) NSMutableArray *myArray;
    @property (nonatomic) MKPinAnnotationColor pinColor;

    -(IBAction) getlocation;


@end

【问题讨论】:

    标签: ios mkmapview mkannotation mkannotationview


    【解决方案1】:

    这不是地图重载瓦片的问题。

    问题在于viewForAnnotation 委托中的代码使用了ann 对象,并错误地假设类实例级ann 对象将与调用委托方法时同步。

    viewForAnnotation 委托不一定按照添加注解的顺序调用,如果地图返回时需要重新显示注解,则可以为同一注解调用多次次进入视野。

    当为先前添加的注解再次调用委托方法时,annannotation 不再指向同一个对象。 ann 现在可能指向最后添加的注释,因此所有注释都更改为它的颜色。

    在该委托方法中,您必须使用annotation 参数,该参数是对地图视图在当前调用中想要查看的注释的引用(这可能与您的外循环)。

    所以这一行:

    MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc] 
        initWithAnnotation:ann reuseIdentifier:@"current"];
    

    应该是:

    MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc] 
        initWithAnnotation:annotation reuseIdentifier:@"current"];
                           ^^^^^^^^^^
    

    并且在检查注解的属性时,使用annotation 参数(并将其转换为您的自定义类以获取自定义属性):

    PinDrop *ann = (PinDrop *)annotation;
    //Note that this local "ann" is NOT the same as the class-level "ann".
    //May want to use a different name to avoid confusion.
    //The compiler may also warn you about this.
    
    if (ann.price == 1)
    ...
    


    一个单独的、不相关但强烈推荐的建议是通过使用dequeueReusableAnnotationViewWithIdentifier 实现注释视图重用。当您有大量注释时,这将提高性能。

    【讨论】:

    • swift 2.0 的任何解决方案?
    猜你喜欢
    • 2015-09-28
    • 1970-01-01
    • 2017-04-09
    • 2011-07-06
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    相关资源
    最近更新 更多