MapKit:在iPhone中缩放地图之前不会显示注释

时间:2013-07-14 15:58:20

标签: sqlite core-data annotations mapkit

我希望一旦点击像“Mapa”这样的工具栏按钮,注释就会显示在可见的地图区域中。数据从CoreData(Sqlite)获取。在iPhone模拟器中一切正常,但是当我在iPhone上测试应用程序时,单击工具栏上的按钮后会显示一些引脚,我需要放大和缩小几次才能获得所有引脚。

第一张图片(http://www.aerodromoschile.com/IMG_0982.PNG)在缩放之前显示屏幕几次,第二张图像(http://www.aerodromoschile.com/IMG_0981.PNG)是我想从开头得到的

你可以帮帮我吗?这是代码

#import "MapViewController.h"
#import "AerodromoAppDelegate.h"
#import "Aerodromo.h"
#import "DetalleViewController.h"
#import <MapKit/MapKit.h>


@implementation mapViewController {
NSArray *locations;
}

@synthesize managedObjectContext;
@synthesize mapView;



- (void)viewDidLoad
{
[super viewDidLoad];

if (self.managedObjectContext == nil)
{
    self.managedObjectContext = [(AerodromoAppDelegate *)[[UIApplication      sharedApplication] delegate] managedObjectContext];
    NSLog(@"After managedObjectContext: %@",  self.managedObjectContext);
}

dispatch_async (dispatch_get_main_queue(), ^{

NSLog(@"Main Thread Code"); 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Aerodromo" inManagedObjectContext:self.managedObjectContext];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];

NSError *error;
NSArray *foundObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (foundObjects == nil) {
    NSLog(@"FATAL_CORE_DATA_ERROR(error)");
    return;
}

if (locations != nil) {
    [self.mapView removeAnnotations:locations];
}

locations = foundObjects;

self.title = @"Mapa Online";

UIBarButtonItem *showuser = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showUser:)];

UIBarButtonItem *boton = [[UIBarButtonItem alloc] initWithTitle:@"Boton" style:UIBarButtonItemStyleDone target:self action:@selector(boton2:)];

NSArray *botones = [[NSArray alloc] initWithObjects:showuser, boton, nil];

self.navigationItem.rightBarButtonItems = botones;


mapView.delegate = self;

// Creamos una coordenada inicial.
CLLocationCoordinate2D initialLocation;
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = self.mapView.userLocation.location.coordinate;
initialLocation.latitude = self.mapView.userLocation.location.coordinate.latitude;
initialLocation.longitude= self.mapView.userLocation.location.coordinate.longitude;


// Esto situará el centro del mapa    
region = MKCoordinateRegionMakeWithDistance(initialLocation, 50000, 50000);
[self.mapView setRegion:region animated:NO];

[self.mapView removeAnnotations:self.mapView.annotations];

 NSLog(@"antotaciones = %d", locations.count);

[self.mapView addAnnotations:locations];

 self.mapView.showsUserLocation=TRUE;

    NSLog(@"fin Thread Code");

}); // termino del queqe

//[self.mapView addAnnotations:locations];
//[self updateLocations];

}


- (void)showUser:(id)sender{
NSLog(@"Boton1");
MKCoordinateRegion region =   MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 50000, 50000);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:NO];
}

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{

    [self.mapView removeAnnotations:self.mapView.annotations];
    [self.mapView addAnnotations:locations];

}


- (void)boton2:(id)sender{
NSLog(@"boton 2");
}


#pragma mark - MKMapViewDelegate

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

if ([annotation isKindOfClass:[Aerodromo class]]) {

    static NSString *identifier = @"Aerodromo";
    MKAnnotationView *annotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    if (annotationView == nil) {
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        //annotationView.animatesDrop = NO;
        annotationView.image = [UIImage imageNamed:@"aero3.png"];
        //annotationView.pinColor = MKPinAnnotationColorGreen;

        UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        [rightButton addTarget:self action:@selector(showLocationDetails:) forControlEvents:UIControlEventTouchUpInside];
        annotationView.rightCalloutAccessoryView = rightButton;
    } else {
        annotationView.annotation = annotation;
    }

    UIButton *button = (UIButton *)annotationView.rightCalloutAccessoryView;
    button.tag = [locations indexOfObject:(Aerodromo *)annotation];

    return annotationView;
}

return nil;
}


- (void)showLocationDetails:(UIButton *)button
{

NSLog(@"se apreto el boton");
//[self performSegueWithIdentifier:@"EditLocation" sender:button];
}

@end

已编辑的代码

这是我正在使用的las代码,我会遇到同样的问题......

- (void)viewDidLoad
{
[super viewDidLoad];

if (self.managedObjectContext == nil)
{
    self.managedObjectContext = [(AerodromoAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    NSLog(@"After managedObjectContext: %@",  self.managedObjectContext);
}

UIBarButtonItem *showuser = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showUser:)];
UIBarButtonItem *boton = [[UIBarButtonItem alloc] initWithTitle:@"Boton" style:UIBarButtonItemStyleDone target:self action:@selector(boton2:)];
NSArray *botones = [[NSArray alloc] initWithObjects:showuser, boton, nil];
self.navigationItem.rightBarButtonItems = botones;

self.title = @"Mapa Online";
mapView.delegate = self;

// Creamos una coordenada inicial.
CLLocationCoordinate2D initialLocation;
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
//region.center = //self.mapView.userLocation.location.coordinate;
initialLocation.latitude = -33.40;//self.mapView.userLocation.location.coordinate.latitude;
initialLocation.longitude= -70.54;//self.mapView.userLocation.location.coordinate.longitude;


// Esto situará el centro del mapa
region = MKCoordinateRegionMakeWithDistance(initialLocation, 50000, 50000);
[self.mapView setRegion:region animated:NO];
self.mapView.showsUserLocation=TRUE;
[self.mapView removeAnnotations:self.mapView.annotations];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    //Anything that is not part of the UI

    NSLog(@"ASync Thread Code");

    NSMutableArray *tempLocations = [[NSMutableArray alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Aerodromo" inManagedObjectContext:self.managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];

    NSError *error;
    NSArray *foundObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (foundObjects == nil) {
        NSLog(@"FATAL_CORE_DATA_ERROR(error)");
        return;
    }

    MKPointAnnotation *location; //If you're not using MKPointAnnotation: replace it
    for (location in foundObjects) {
        [tempLocations addObject:location];
    }
    locations = tempLocations.copy;

    dispatch_sync(dispatch_get_main_queue(), ^{

        //Update the UI
        NSLog(@"Getting back to the UI");

        NSLog(@"antotaciones = %d, %@", locations.count, locations);

        if (locations != nil) {
            [self.mapView removeAnnotations:self.mapView.annotations];
            [self.mapView addAnnotations:locations];
        }

    });
});

NSLog(@"fin Thread Code");

}

感谢您的帮助wkberg,当我使用NSLog时(@“antotaciones =%d,%@”,locations.count,locations);要知道数据发生了什么我意识到在第7行之后NSFetchRequest没有加载数据

这是控制台:

2013-07-16 12:10:18.007 Aerodromo[13922:1207] ASync Thread Code
2013-07-16 12:10:18.045 Aerodromo[13922:907] Getting back to the UI
2013-07-16 12:10:18.090 Aerodromo[13922:907] antotaciones = 351, (
"<Aerodromo: 0x1f0b0040> (entity: Aerodromo; id: 0x1f0ad580 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p1> ; data: {\n    Ancho1 = 45;\n    Ancho2 = \"\";\n    Ancho3 = \"\";\n    Ciudad = \"Arica \";\n    Desig = SCAR;\n    Elev = \"123 -166\";\n    FrecTerr = IFR;\n    FrecTorre = 1;\n    Fuel = JP1;\n    Fuel2 = \"AVGAS 100/130\";\n    IdAd = 1;\n    IndexRegion = 1;\n    Larg1 = 2170;\n    Larg2 = \"\";\n    Larg3 = \"\";\n    LatG = 18;\n    LatM = 20;\n    LatS = 55;\n    Latitud = \"-18.349\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 70;\n    LonM = 20;\n    LonS = 19;\n    Longitud = \"-70.339\";\n    Nombre = Chacalluta;\n    NumeroPistas = 1;\n    Pista1 = \"02-20\";\n    Pista2 = \"\";\n    Pista3 = \"\";\n    RegionOrd = 15;\n    Superficie = \"Hormig\\U00f3n\";\n    Superficie2 = \"\";\n    Superficie3 = \"\";\n    Telefono = \"(58) 211116\";\n    TieneMetar = 1;\n    Uso = \"P\\U00daBLICO\";\n    frec = \"<relationship fault: 0x21d8e110 'frec'>\";\n    pdf = \"<relationship fault: 0x21d8e460 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b0470> (entity: Aerodromo; id: 0x1f098d30 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p2> ; data: {\n    Ancho1 = 23;\n    Ancho2 = \"\";\n    Ancho3 = \"\";\n    Ciudad = \"Arica \";\n    Desig = SCAE;\n    Elev = 328;\n    FrecTerr = 0;\n    FrecTorre = 0;\n    Fuel = \"No Tiene\";\n    Fuel2 = \"\";\n    IdAd = 2;\n    IndexRegion = 1;\n    Larg1 = 800;\n    Larg2 = \"\";\n    Larg3 = \"\";\n    LatG = 18;\n    LatM = 30;\n    LatS = 36;\n    Latitud = \"-18.51\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 70;\n    LonM = 17;\n    LonS = 21;\n    Longitud = \"-70.289\";\n    Nombre = \"El Buitre\";\n    NumeroPistas = 1;\n    Pista1 = \"09-27\";\n    Pista2 = \"\";\n    Pista3 = \"\";\n    RegionOrd = 15;\n    Superficie = Asfalto;\n    Superficie2 = \"\";\n    Superficie3 = \"\";\n    Telefono = \"(58) 201500 Anexo 31216\";\n    TieneMetar = 0;\n    Uso = MILITAR;\n    frec = \"<relationship fault: 0x21e711e0 'frec'>\";\n    pdf = \"<relationship fault: 0x21e715e0 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b0870> (entity: Aerodromo; id: 0x1f0a09c0 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p3> ; data: {\n    Ancho1 = 45;\n    Ancho2 = \"\";\n    Ancho3 = \"\";\n    Ciudad = \"Iquique \";\n    Desig = SCDA;\n    Elev = \"97-157\";\n    FrecTerr = \"VFR - IFR\";\n    FrecTorre = 1;\n    Fuel = JP1;\n    Fuel2 = \"AVGAS 100/130\";\n    IdAd = 3;\n    IndexRegion = 2;\n    Larg1 = 3350;\n    Larg2 = \"\";\n    Larg3 = \"\";\n    LatG = 20;\n    LatM = 32;\n    LatS = 07;\n    Latitud = \"-20.535\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 70;\n    LonM = 10;\n    LonS = 53;\n    Longitud = \"-70.181\";\n    Nombre = \"Diego Aracena\";\n    NumeroPistas = 1;\n    Pista1 = \"19-01\";\n    Pista2 = \"\";\n    Pista3 = \"\";\n    RegionOrd = 1;\n    Superficie = \"Hormig\\U00f3n\";\n    Superficie2 = \"\";\n    Superficie3 = \"\";\n    Telefono = \"(57)461200\";\n    TieneMetar = 1;\n    Uso = \"P\\U00daBLICO\";\n    frec = \"<relationship fault: 0x21e71d00 'frec'>\";\n    pdf = \"<relationship fault: 0x21e71e70 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b0670> (entity: Aerodromo; id: 0x1f0a09a0 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p4> ; data: {\n    Ancho1 = 20;\n    Ancho2 = 20;\n    Ancho3 = \"\";\n    Ciudad = \"Pica \";\n    Desig = SCKP;\n    Elev = 12468;\n    FrecTerr = 0;\n    FrecTorre = 0;\n    Fuel = \"No Tiene\";\n    Fuel2 = \"\";\n    IdAd = 4;\n    IndexRegion = 2;\n    Larg1 = 3200;\n    Larg2 = 1034;\n    Larg3 = \"\";\n    LatG = 20;\n    LatM = 44;\n    LatS = 08;\n    Latitud = \"-20.736\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 68;\n    LonM = 41;\n    LonS = 42;\n    Longitud = \"-68.69499999999999\";\n    Nombre = Coposa;\n    NumeroPistas = 2;\n    Pista1 = \"17-35\";\n    Pista2 = \"10-28\";\n    Pista3 = \"\";\n    RegionOrd = 1;\n    Superficie = Asfalto;\n    Superficie2 = Tierra;\n    Superficie3 = \"\";\n    Telefono = \"(57)417777\";\n    TieneMetar = 0;\n    Uso = PRIVADO;\n    frec = \"<relationship fault: 0x21e72b80 'frec'>\";\n    pdf = \"<relationship fault: 0x21e72f70 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b0a50> (entity: Aerodromo; id: 0x1f0907c0 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p5> ; data: {\n    Ancho1 = 30;\n    Ancho2 = \"\";\n    Ancho3 = \"\";\n    Ciudad = \"Pozo Almonte\";\n    Desig = SCNV;\n    Elev = 3172;\n    FrecTerr = 0;\n    FrecTorre = 0;\n    Fuel = \"No Tiene\";\n    Fuel2 = \"\";\n    IdAd = 5;\n    IndexRegion = 2;\n    Larg1 = 1077;\n    Larg2 = \"\";\n    Larg3 = \"\";\n    LatG = 20;\n    LatM = 44;\n    LatS = \"05,4\";\n    Latitud = \"-20.735\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 69;\n    LonM = 37;\n    LonS = \"32,6\";\n    Longitud = \"-69.626\";\n    Nombre = \"Nueva Victoria\";\n    NumeroPistas = 1;\n    Pista1 = \"09-27\";\n    Pista2 = \"\";\n    Pista3 = \"\";\n    RegionOrd = 1;\n    Superficie = Vichufita;\n    Superficie2 = \"\";\n    Superficie3 = \"\";\n    Telefono = \"(57) 413620\";\n    TieneMetar = 0;\n    Uso = PRIVADO;\n    frec = \"<relationship fault: 0x21e739e0 'frec'>\";\n    pdf = \"<relationship fault: 0x21e73800 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b0c20> (entity: Aerodromo; id: 0x1f0920e0 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p6> ; data: {\n    Ancho1 = 18;\n    Ancho2 = \"\";\n    Ancho3 = \"\";\n    Ciudad = \"Antofagasta \";\n    Desig = SCGU;\n    Elev = 3347;\n    FrecTerr = 0;\n    FrecTorre = 0;\n    Fuel = \"No Tiene\";\n    Fuel2 = \"\";\n    IdAd = 6;\n    IndexRegion = 3;\n    Larg1 = 1200;\n    Larg2 = \"\";\n    Larg3 = \"\";\n    LatG = 24;\n    LatM = 8;\n    LatS = 11;\n    Latitud = \"-24.136\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 69;\n    LonM = 49;\n    LonS = 43;\n    Longitud = \"-69.82899999999999\";\n    Nombre = \"Aguas Blancas\";\n    NumeroPistas = 1;\n    Pista1 = \"13-31\";\n    Pista2 = \"\";\n    Pista3 = \"\";\n    RegionOrd = 2;\n    Superficie = Tierra;\n    Superficie2 = \"\";\n    Superficie3 = \"\";\n    Telefono = \"(2) 2063737\";\n    TieneMetar = 0;\n    Uso = PRIVADO;\n    frec = \"<relationship fault: 0x21e744d0 'frec'>\";\n    pdf = \"<relationship fault: 0x21e74920 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b1020> (entity: Aerodromo; id: 0x1f0a1970 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p7> ; data: {\n    Ancho1 = 50;\n    Ancho2 = \"\";\n    Ancho3 = \"\";\n    Ciudad = \"Antofagasta \";\n    Desig = SCFA;\n    Elev = \"352- 455\";\n    FrecTerr = \"VFR - IFR\";\n    FrecTorre = 1;\n    Fuel = JP1;\n    Fuel2 = \"AVGAS 100/130\";\n    IdAd = 7;\n    IndexRegion = 3;\n    Larg1 = 2599;\n    Larg2 = \"\";\n    Larg3 = \"\";\n    LatG = 23;\n    LatM = 26;\n    LatS = 40;\n    Latitud = \"-23.444\";\n    Limitaciones = \"\";\n    Limitaciones2 = \"\";\n    Limitaciones3 = \"\";\n    LonG = 70;\n    LonM = 26;\n    LonS = 42;\n    Longitud = \"-70.44499999999999\";\n    Nombre = \"Cerro Moreno\";\n    NumeroPistas = 1;\n    Pista1 = \"01-19\";\n    Pista2 = \"\";\n    Pista3 = \"\";\n    RegionOrd = 2;\n    Superficie = Asfalto;\n    Superficie2 = \"\";\n    Superficie3 = \"\";\n    Telefono = \"(55) 269077\";\n    TieneMetar = 1;\n    Uso = \"P\\U00daBLICO\";\n    frec = \"<relationship fault: 0x21e75370 'frec'>\";\n    pdf = \"<relationship fault: 0x21e75190 'pdf'>\";\n})",
"<Aerodromo: 0x1f0b1770> (entity: Aerodromo; id: 0x1f0a41c0 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p8> ; data: <fault>)",
"<Aerodromo: 0x1f0b1f00> (entity: Aerodromo; id: 0x1f0ad660 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p9> ; data: <fault>)",
"<Aerodromo: 0x1f0b11e0> (entity: Aerodromo; id: 0x1f071c50 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p10> ; data: <fault>)",
"<Aerodromo: 0x1f0b1b50> (entity: Aerodromo; id: 0x1f0a4930 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p11> ; data: <fault>)",
"<Aerodromo: 0x1f0b13c0> (entity: Aerodromo; id: 0x1f0a3190 <x-coredata://DEC0D4FE-F4A8-4739-9974-076071695E99/Aerodromo/p12> ; data: <fault>)", 

1 个答案:

答案 0 :(得分:0)

您调度addAnnotations async。注释是UI的一部分,应该在主线程上。在缩放地图之前不会添加它们的原因是因为您的regionWillChangeAnimated代码。当你缩放时,iPhone上的异步调度已经完成,但是当你在viewDidLoad中添加注释时,它还没有。

使用GCD解决您的问题:

在你的viewDidLoad做类似的事情:

-(void)viewDidLoad {
//Do UI stuff here:
//the mapView setup
//Region set
//and any other UI like: UILabels, UIbuttons etc.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//So now we start the async part:

dispatch_async(queue, ^{
 //Anything that is not part of the UI
 //Get your data for the annotations

 //And now get back to the main_queue sync:

    dispatch_sync(dispatch_get_main_queue(), ^{
        locations = foundObjects; //As in your code
        //Update the UI
        NSLog(@"Getting back to the UI");

        if (locations != nil) {
         [self.mapView removeAnnotations:self.mapView.annotations]; //mapView.annotations to remove all...
         [self.mapView addAnnotations:locations];
        }

    });
});
NSLog(@"End of viewDidLoad");
}

来自评论:

如果仍然没有出现所有注释。检查在[self.mapView addAnnotations:locations];阵列完成之前是否未调用locations。 使用您的regionWillChangeAnimated将地图调整为用户位置时,setRegion:region可以完成此操作。

NSFetch问题:

好的,因为我对NSFetchRequest不熟悉,请耐心等待:

我相信您的NSFetchRequest不会立即使用所有注释填充您的位置数组。 尝试使用NSMutableArray。我已经更新了代码:

NSMutableArray *tempLocations = [[NSMutableArray alloc] init];

//Do your fetchRequest

//Then do the following, however I don't know exactly as what your `locations` are stored so you might need to change it a bit:
//I believe your annotations are kind of a Aerodromo class? So then:

for (Aerodromo *aerodromoAnn in fetchedObjects) {
    [tempLocations addObject:aerodromoAnn];
}
/
//Then update your original locations array:
locations = tempLocations.copy;

//update the main queue again

很抱歉,您必须检查,因为我无法在没有数据库的情况下进行测试