簡體   English   中英

構建MapView注釋非常慢

[英]Building MapView Annotations is very slow

我有一個應用程序,可在MapView中顯示約100個注釋(帶有自定義圖釘圖像,標注附件和注釋圖像)。 在構建注釋時,我在注釋和建築物之間存儲了鏈接,因此我可以分配正確的建築物並隨后打開正確的序列。

在iOS 6中,它們的構建速度非常快,我在添加它們時也啟用了動畫,因此一個圖釘掉到了另一個圖釘上,但是在iOS7中使用Apple Maps不再可用(?)。 現在在我的iPhone 4S上構建這100條注釋需要1秒鍾,這太長了。 無論如何,有沒有改進代碼?

- (void)viewDidLoad

...

//creating annotations
    annotationlink = [[NSMutableArray alloc] init];

    for (int i = 0; i < data.count; i++) {
        NSDictionary *dataItem = [data objectAtIndex:i];

        //storing annotation in array for link
        Annotation *buildingannotation = [[Annotation alloc] init];
        NSNumber *index = [NSNumber numberWithInteger:i];
        NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:index, indexKey, buildingannotation, annotationKey, nil];
        [annotationlink addObject:dict];

        buildingannotation.title = [dataItem objectForKey:@"Building"];
        buildingannotation.subtitle = [dataItem objectForKey:@"Info"];

        MKCoordinateRegion buildingcoordinates;
        buildingcoordinates.center.latitude = [[dataItem objectForKey:@"Latitude"] floatValue];
        buildingcoordinates.center.longitude = [[dataItem objectForKey:@"Longitude"] floatValue];
        buildingannotation.coordinate = buildingcoordinates.center;

        [self.mapView addAnnotation:buildingannotation];
    }


- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]]){
        return nil;
    }

    MKAnnotationView *pinView = (MKAnnotationView *)
    [self.mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];

    MKAnnotationView *customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
    customAnnotationView.canShowCallout = YES;

    //right button to detail view
    UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    customAnnotationView.rightCalloutAccessoryView = disclosureButton;

    //left button for image
    NSInteger *buildingindex = [self getIndex:annotation];
    NSDictionary *dataItem = [data objectAtIndex:buildingindex];
    NSString* filename = [dataItem objectForKey:@"Thumb"];
    filename = [filename stringByAppendingString:@"@2x.jpg"];

    NSString* resourceimagePath = [resourcePath stringByAppendingPathComponent:filename];
    Image = [UIImage imageWithContentsOfFile:resourceimagePath];

    UIImageView *AnnotationThumb = [[UIImageView alloc] initWithImage:Image];
    AnnotationThumb.frame = CGRectMake(0, 0, 31, 31);
    customAnnotationView.leftCalloutAccessoryView = AnnotationThumb;

    //annotation image
    customAnnotationView.image = [UIImage imageNamed:@"Annotation_white.png"];

    return customAnnotationView;
    return pinView;
}

以下函數使用nspredicate獲取當前注釋的索引,以使用字典過濾數組。 這樣的優點是事實,當calloutAccessoryControlTapped時,我也可以使用它:

-(NSInteger*) getIndex:(Annotation*)searchannotation
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", annotationKey, searchannotation];
    NSArray *filteredarray = [annotationlink filteredArrayUsingPredicate:predicate];
    NSDictionary *building = [filteredarray objectAtIndex:0];
    NSInteger *buildingIndex = [[building objectForKey:indexKey] integerValue];
    return buildingIndex;
}

使用iPhone 4S,在加載視圖后的1.14秒內建立了最后一個引腳。

如果我手動搜索注釋鏈接數組而不是使用nspredicate函數,例如:

//left button for image
    int buildingIndex;
    for (int i = 0; i < annotationlink.count; i++) {
        NSDictionary *annotationDict = [annotationlink objectAtIndex:i];
        if ([[annotationDict objectForKey:annotationKey] isEqual:annotation]) {
            buildingIndex= [[annotationDict objectForKey:indexKey] integerValue];
            i = annotationlink.count;
        }
    }

    NSDictionary *dataItem = [data objectAtIndex:buildingIndex];

日志顯示最后一個引腳建立在viewDidLoad之后的1.89秒處。

如果我在viewDidApper中而不是viewDidLoad中創建注釋,則視圖會立即顯示為偏離路線,但是背景需要一些時間才能加載,因此在放下銷釘之前,所有部件都是灰色的,這也不是很好。

謝謝安娜的建議! 我實現了如下改進:

Annotation.h:

#import <MapKit/MKAnnotation.h> 

@interface Annotation : NSObject <MKAnnotation> {} 
@property(nonatomic, assign) CLLocationCoordinate2D coordinate; 
@property(nonatomic, copy) NSString *title; 
@property(nonatomic, copy) NSString *subtitle; 
@property NSInteger *ID; 
@end 

Annotation.m:

#import "Annotation.h" 

@implementation Annotation 
@synthesize coordinate, title, subtitle, ID; 
@end 

ViewDidAppear:

//creating annotations 
for (int i = 0; i < data.count; i++) { 
   NSDictionary *dataItem = [data objectAtIndex:i]; 
   Annotation *buildingannotation = [[Annotation alloc] init]; 
   buildingannotation.ID = i; 
   buildingannotation.title = [dataItem objectForKey:@"Building"]; 
   buildingannotation.subtitle = [dataItem objectForKey:@"Subtitle"]; 

   MKCoordinateRegion buildingcoordinates; 
   buildingcoordinates.center.latitude = [[dataItem objectForKey:@"Latitude"] floatValue];    
   buildingcoordinates.center.longitude = [[dataItem objectForKey:@"Longitude"] floatValue]; 
   buildingannotation.coordinate = buildingcoordinates.center; 

   [self.mapView addAnnotation:buildingannotation]; 
} 

viewForAnnotation:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]]){
        return nil;
}

MKAnnotationView *pinView = (MKAnnotationView *)
[self.mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];

if (pinView == nil) {
    MKAnnotationView *customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
    customAnnotationView.canShowCallout = YES;

    //right button to detail view
    UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    customAnnotationView.rightCalloutAccessoryView = disclosureButton;

    //left button for image
    Annotation *buildingAnnotation = (Annotation *)annotation;
    NSInteger *buildingindex = buildingAnnotation.ID;

    NSString *filePath = [thumbname objectAtIndex:buildingindex];
    UIImageView *AnnotationThumb = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filePath]];
    AnnotationThumb.frame = CGRectMake(0, 0, 31, 31);
    customAnnotationView.leftCalloutAccessoryView = AnnotationThumb;

    //annotation image
    customAnnotationView.image = [UIImage imageNamed:@"Annotation_white.png"];

    return customAnnotationView;
} else {
    pinView.annotation = annotation;
}

return pinView;
}

大喊:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    Annotation *buildingAnnotation = (Annotation *)view.annotation;
    selectedbuilding = buildingAnnotation.ID;
    [self performSegueWithIdentifier:@"DetailViewController" sender:self];
}

仍需要一些時間來顯示所有注釋。 有機會進一步改進代碼嗎?

我更新了關於Anna的回復和PhotosByLocation示例應用程序的vievForAnnotation函數。 它現在可以工作,我希望這是實現重用的正確方法...

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]]){
        return nil;
    }

    MKAnnotationView *buildingAnnotationView = (MKAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];

    if (buildingAnnotationView) {
        [buildingAnnotationView prepareForReuse];
    } else {
        buildingAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
        buildingAnnotationView.canShowCallout = YES;

        //right button to detail view
        UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        buildingAnnotationView.rightCalloutAccessoryView = disclosureButton;

        //annotation image
        buildingAnnotationView.image = [UIImage imageNamed:@"Annotation_white.png"];
    }

    //left button for image
    Annotation *buildingAnnotation = (Annotation *)annotation;
    NSInteger *buildingindex = buildingAnnotation.ID;

    NSString *filePath = [thumbname objectAtIndex:buildingindex];
    UIImageView *AnnotationThumb = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filePath]];
    AnnotationThumb.frame = CGRectMake(0, 0, 31, 31);
    buildingAnnotationView.leftCalloutAccessoryView = AnnotationThumb;

    return buildingAnnotationView;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM