Neckbeard_StageLevel7
Neckbeard_StageLevel7

Reputation: 48

removeOverlay:overlay not working

I'm a new guy in the XCode realm and was wondering if someone could help me out.

Essentially, I'm playing around with WWDC2010's TileMap project example and am trying to figure out a way to hide their NOAA chart using a segmented controller.

I can activate the overlay and it displays fine, but I can't for the life of me remove it using a segmented controller.

Here's some code from the header file:

@interface ViewController : UIViewController <MKMapViewDelegate> {
    IBOutlet MKMapView *map;
    IBOutlet UISegmentedControl *controller;
}    
- (IBAction)switchMap:(id)sender;
@end

and here's the code for the .m:

- (void)viewDidLoad {
    [super viewDidLoad];  
    NSLog(@"initial view loaded"); 
}  

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay {  

    TileOverlayView *view = [[TileOverlayView alloc] initWithOverlay:overlay];     
    view.tileAlpha = 1;
    return view;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

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

- (IBAction)switchMap:(id)overlay {

    if (controller.selectedSegmentIndex == 0) {
        NSLog(@"welp... it loaded...");
        [map removeOverlay:overlay];
    }

    if (controller.selectedSegmentIndex == 1) {

        NSLog(@"Map Overlay works");
        NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Tiles"];
        TileOverlay *overlay = [[TileOverlay alloc] initWithTileDirectory:tileDirectory];
        [map addOverlay:overlay];

        MKMapRect visibleRect = [map mapRectThatFits:overlay.boundingMapRect];
        visibleRect.size.width /= 2;
        visibleRect.size.height /= 2;
        visibleRect.origin.x += visibleRect.size.width / 2;
        visibleRect.origin.y += visibleRect.size.height / 2;
        map.visibleMapRect = visibleRect;

    }


    if (controller.selectedSegmentIndex == 2) {
        NSLog(@"But... overlay isnt hiding waa");
        NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Tiles"];
        TileOverlay *overlay = [[TileOverlay alloc] initWithTileDirectory:tileDirectory];
        [map removeOverlay:overlay]; }
     }

Upvotes: 2

Views: 1795

Answers (1)

user467105
user467105

Reputation:

In a control action method, the first parameter (no matter what you name it) is always the object that called the method.

Here, the control is a UISegmentedControl so the parameter that gets passed to switchMap: is a reference to that control. In the .h you've declared the parameter with the name sender but in the .m it's named overlay.

Regardless of the name, it's still the segmented control object so passing it to removeOverlay is meaningless and will do nothing.


So in this code:

if (controller.selectedSegmentIndex == 0) {
    NSLog(@"welp... it loaded...");
    [map removeOverlay:overlay];
}

overlay is pointing to the segmented control and so the removeOverlay does nothing.


In this code:

if (controller.selectedSegmentIndex == 2) {
    NSLog(@"But... overlay isnt hiding waa");
    NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Tiles"];
    TileOverlay *overlay = [[TileOverlay alloc] initWithTileDirectory:tileDirectory];
    [map removeOverlay:overlay]; }

You are creating a new local overlay object (the compiler is also probably giving you a warning about a local variable hiding the parameter). This new object is separate from the overlay that was already added to the map. Calling removeOverlay on this new object does nothing because this new instance was never added to the map in the first place.


To remove an existing overlay, you either have to keep an ivar reference to it when you add it and pass that ivar to remove or find it in the map view's overlays array.

However, if you will ever have only one overlay, you can pass the first object in the map view's overlays array or just call removeOverlays (plural) and pass the whole array:

if (map.overlays.count > 0)
    [map removeOverlay:[map.overlays objectAtIndex:0]];

//OR...

if (map.overlays.count > 0)
    [map removeOverlays:map.overlays];

Upvotes: 1

Related Questions