3

I have a method that inserts annotations in the map. This method is called by a delegate method of map.

The problem is that the annotations don't appear in map. I have to touch the map one more time to show the annotations.

After inserting the annotations, I'm using [CATRansaction flush], but it don't work.

Above the code:

Map delegated method:

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

    log(@"region changed");

    if (_userRegion.center.latitude) {
        log(@"Move map. New location: %f X %f", self.mapView.centerCoordinate.latitude, self.mapView.centerCoordinate.longitude);

        NSDictionary *coordinates = @{
                                      @"latitude": [NSString stringWithFormat:@"%f", self.mapView.centerCoordinate.latitude],
                                      @"longitude": [NSString stringWithFormat:@"%f", self.mapView.centerCoordinate.longitude]
                                      };
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(updateMap:) object:coordinates];
        [thread start];
    }

    if(_userMenuOpened){
        [self closeUserMenu];
    }

    if(_settingsMenuOpened){
        [self closeSettingsMenu];
    }

}

Method that inserts the annotation:

- (void) updateMap:(NSDictionary *) coordinates {

    NSArray *annotationsInMap = [self.mapView annotations];

    _busStops = [_ws getStations:10 lat:[[coordinates valueForKey:@"latitude"] doubleValue] lng:[[coordinates valueForKey:@"longitude"] doubleValue]];

    for(NSString *stop in _busStops) {

        BOOL inMap = NO;
        BPBusStopAnnotation *annotation = [[BPBusStopAnnotation alloc] initWithData:stop];

        //Se tiver annotation no mapa verifica se os que vem no WS sao os mesmos
        if(annotationsInMap.count > 0){

            for(BPBusStopAnnotation *pt in annotationsInMap){
                if(pt && ![pt isKindOfClass:[MKUserLocation class]]){

                    if([annotation.codigo isEqual:pt.codigo]){
                        inMap = YES;
                        break;

                    }
                }
            }

        }

        if (!inMap) {
            [self.mapView addAnnotation:annotation];
        }

    }

    [CATransaction flush];

}

Thank's!!!

Alessandro Garcez
  • 728
  • 2
  • 6
  • 25
  • 1
    Related: http://stackoverflow.com/questions/1995245/iphone-mapview-interrupted –  Jan 11 '14 at 03:18

2 Answers2

2

In "updateMap" method, I changed

if (!inMap) {
    [self.mapView addAnnotation:annotation];
}

for

[self.mapView performSelectorOnMainThread: @selector(addAnnotation:) withObject: annotation waitUntilDone: YES];
Alessandro Garcez
  • 728
  • 2
  • 6
  • 25
1

You said it yourself: it's the thread. You mustn't do anything that affects the interface on anything but the main thread, and that's the problem here.

(And while you are fixing this, if I were you, I would never use NSThread. It is the worst of all possible ways to do iOS threading.)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Thank's for your answer @matt, but how can I solve my problem? I need to call ws in that delegate method, but if I do that in main thread, it freezes the screen until finish the ws call. – Alessandro Garcez Jan 10 '14 at 19:05
  • 1
    You step into a background thread when you want to do stuff in the background, and back onto the main thread when you want to do stuff in the main thread (e.g. update the interface). – matt Jan 10 '14 at 19:17
  • 1
    It might help you to stop and learn about threading in iOS before you go any further. See [the Threads chapter of my book](http://www.apeth.com/iOSBook/ch38.html), for example. – matt Jan 10 '14 at 19:18