2011-10-27 10 views
8

मेरे पास मेरे ऐप में एक मॉडल दृश्य है जो UIMapView प्रदर्शित करता है। इसके बाद मैं इस मानचित्र दृश्य (नीचे कोड) में बड़ी संख्या में एनोटेशन (800 से अधिक) जोड़ता हूं।MKMapView के लिए अनुकूलन कोड - एनोटेशन की बड़ी संख्या

समस्या यह है कि उपयोगकर्ता को एक मिनट या तो प्रतीक्षा करने के लिए मजबूर होना पड़ता है जबकि सभी पिन लोड होते हैं। मानचित्र पर सभी 800 पिन होने पर भी ऐप आलसी हो जाता है।

क्या कोई सुझाव दे सकता है कि मैं नीचे अपना कोड कैसे सुधार सकता हूं?

धन्यवाद।

#import "MapView.h" 
#import "MapPlaceObject.h" 


@implementation MapView 
@synthesize mapViewLink, mapLocations, detail, failedLoad; 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
if (self) { 
    // Custom initialization 
} 
return self; 
} 

-(void)addPins 
{ 

for (MapPlaceObject * info in mapLocations) { 


    double latitude = info.longitude; 
    double longitude = info.latitude; 

    NSString * name = info.name; 
    NSString * addressline = info.addressOne; 
    NSString * postcode = info.postCode; 

    NSString * addresscomma = [addressline stringByAppendingString:@", "]; 
    NSString * address = [addresscomma stringByAppendingString:postcode]; 

    CLLocationCoordinate2D coordinate; 
    coordinate.latitude = latitude; 
    coordinate.longitude = longitude; 
    MyLocation *annotation = [[[MyLocation alloc] initWithName:name address:address coordinate:coordinate] autorelease]; 


    [mapViewLink addAnnotation:annotation]; 

} 
} 

- (void)showLinks : (id)sender { 


if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
    detail = [[DetailViewController alloc] initWithNibName:@"DetailViewController-iPad" bundle:nil]; 
} 

else if (!detail) { 

    NSLog(@"Detail is None"); 

    detail = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; 

} 

int uniqueID = ((UIButton *)sender).tag; 

//PlaceObject *info = [mapLocations objectAtIndex:uniqueID]; 

detail.UniqueID = uniqueID; 
detail.hidesBottomBarWhenPushed = YES; 

[self.navigationController pushViewController:detail animated:YES]; 

self.detail = nil; 

[detail release]; 

} 

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

if (annotation == mapView.userLocation){ 
    return nil; //default to blue dot 
}  

MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentloc"]; 
annView.pinColor = MKPinAnnotationColorRed; 

nameSaved = annotation.title; 

for (PlaceObject * info in mapLocations) { 

    if (info.name == nameSaved) { 

     saveID = info.UniqueID; 

    } 
} 

UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
advertButton.frame = CGRectMake(0, 0, 23, 23); 
advertButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 
advertButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; 

[advertButton addTarget:self action:@selector(showLinks:) forControlEvents:UIControlEventTouchUpInside]; 

advertButton.tag = saveID; 

annView.rightCalloutAccessoryView = advertButton; 

annView.animatesDrop=TRUE; 
annView.canShowCallout = YES; 
annView.calloutOffset = CGPointMake(-5, 5); 
return annView; 

} 

- (void)dealloc 
{ 
[mapViewLink release]; 
[mapLocations release]; 
[detail release]; 
self.failedLoad = nil; 
[failedLoad release]; 
[super dealloc]; 
} 

- (void)didReceiveMemoryWarning 
{ 
// Releases the view if it doesn't have a superview. 
[super didReceiveMemoryWarning]; 

// Release any cached data, images, etc that aren't in use. 
} 

- (void)viewWillAppear:(BOOL)animated { 

if (firstTime) { 

    CLLocationCoordinate2D zoomLocation; 

    zoomLocation.latitude = 51.50801; 
    zoomLocation.longitude = -0.12789; 

    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 15*METERS_PER_MILE, 15*METERS_PER_MILE); 

    MKCoordinateRegion adjustedRegion = [mapViewLink regionThatFits:viewRegion];     

    [mapViewLink setRegion:adjustedRegion animated:YES]; 

    firstTime = NO; 

}  
} 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

firstTime = YES; 

failedLoad = [[NSMutableArray alloc]init]; 

self.mapLocations = [BluePlaqueDatabase database].mapInfo; 

[self addPins]; 
} 

- (void)viewDidUnload 
{ 
[mapViewLink release]; 
mapViewLink = nil; 
[super viewDidUnload]; 
// Release any retained subviews of the main view. 
// e.g. self.myOutlet = nil; 
} 

उत्तर

10

दो सबसे बड़ी गति सुधार तुम यहाँ कर सकते हैं:

  • लागू एनोटेशन दृश्य फिर से उपयोग (अभी यह कोई नया दृश्य हर बार यह एक एनोटेशन को दिखाने के लिए भी एक ही है, तो जरूरत है बनाता है एक बार फिर से देखने में आता है।
  • बदलें कि UniqueID कैसे सेट किया गया है। इसे सेट करने के लिए, कोड वर्तमान में एनोटेशन व्यू बनाने पर हर एनोटेशन के माध्यम से लूपिंग कर रहा है (जो किसी भी समय मानचित्र दृश्य ज़ूम या स्क्रॉल हो सकता है- - केवल प्रारंभिक समय नहीं)

पहले, बजाय viewForAnnotation विधि में UniqueID के लिए खोज और एक बटन टैग का उपयोग कर, एनोटेशन पहचानकर्ता पारित अपने कस्टम एनोटेशन वर्गMyLocation करने के लिए एक संपत्ति के रूप में UniqueID जोड़ सकते हैं और गुण सेट जब आप टिप्पणी जोड़ने के लिए की addPins में ही:

annotation.uniqueID = info.UniqueID; // <-- give id to annotation itself 
[mapViewLink addAnnotation:annotation];  

तुम भी uniqueID एक पैरामीटर के रूप initWithName विधि के बजाय अलग से संपत्ति देने की जोड़ सकता है।


इसके बाद, एनोटेशन दृश्य फिर से उपयोग लागू करने के लिए, viewForAnnotation विधि इस तरह दिखना चाहिए:

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

    if (annotation == mapView.userLocation){ 
     return nil; //default to blue dot 
    }  

    NSString *reuseId = @"StandardPin"; 
    MKPinAnnotationView *annView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseId]; 
    if (annView == nil) 
    { 
     annView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId] autorelease]; 

     annView.pinColor = MKPinAnnotationColorRed; 
     annView.animatesDrop = YES; 
     annView.canShowCallout = YES; 
     annView.calloutOffset = CGPointMake(-5, 5); 

     UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
     advertButton.frame = CGRectMake(0, 0, 23, 23); 
     advertButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 
     advertButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; 

     annView.rightCalloutAccessoryView = advertButton; 
    } 
    else 
    { 
     //update the annotation property if view is being re-used... 
     annView.annotation = annotation; 
    } 

    return annView; 
} 


अंत में, बटन प्रेस करने के लिए जवाब है और यह पता लगाने की जो UniqueID विस्तार को दिखाने के लिए करने के लिए

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view 
      calloutAccessoryControlTapped:(UIControl *)control 
{ 
    MyLocation *myLoc = (MyLocation *)view.annotation; 

    int uniqueID = myLoc.uniqueID; 

    NSLog(@"calloutAccessoryControlTapped, uid = %d", uniqueID); 

    //create, init, and show the detail view controller here... 
} 


: के लिए, calloutAccessoryControlTapped प्रतिनिधि विधि को लागूइन सभी परिवर्तनों के बाद, केवल एनोटेशन की आरंभिक लोडिंग अधिकतर समय लेती है। यदि यह अभी भी एक समस्या है, तो एक समाधान केवल एनोटेशन जोड़ना है जो वर्तमान में प्रदर्शित क्षेत्र में दिखाई देगा और एनोटेशन को जोड़/हटा देगा क्योंकि उपयोगकर्ता दृश्य क्षेत्र को बदलता है।

4

मैं पूरी तरह से अन्ना से सहमत हूं। लेकिन मान लें कि 800 एनोटेशन व्यू एक ही समय में एक चरम अंतराल इंटरफ़ेस का परिणाम होगा। इसलिए यदि आपके मानचित्र को स्क्रॉलिंग या ज़ूमिंग जैसे उपयोगकर्ता इंटरैक्शन प्रदान करना चाहिए तो आप अपने एनोटेशन दृश्यों के किसी प्रकार के क्लस्टरिंग को बेहतर तरीके से लागू कर सकते हैं।

संबंधित मुद्दे