Annotation callout title does not change

2019-05-29 08:38发布

问题:

I have searched but i didn't found any solution to my problem. I want to change already added pin. And here is my code. I'm getting "Code Here" in console.

I have in .h

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView         *)annotationView;

myViewController.m

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView
{
    userPins *myAnnot = (userPins *)annotationView.annotation;
    [myAnnot setTitle:@"o21"];
    NSLog(@"Code here!");
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    static NSString *identifier = @"userPins";   
    if ([annotation isKindOfClass:[userPins class]]) {

        MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        } else {
            annotationView.annotation = annotation;
        }

        annotationView.image = [UIImage imageNamed:@"mapMarker-blue.png"];
        annotationView.calloutOffset = CGPointMake(0,0);

        UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        annotationView.rightCalloutAccessoryView = detailButton;

        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;

        return annotationView;

    }

    return nil;   

}

In userPins.m i have. But i didn't do this with setTitle too.

- (void)setTitle:(NSString *)title {
    if (_subtitle != subtitle) {
        [_subtitle release];
        _subtitle = [subtitle retain];
    }
}

- (NSString *)title{
    return @"okan";
}

Edit: @AnnaKarenina

I have tried all. But setTitle is not running. I'm going crazy! This is all of my code. And I'm not getting errors.

userpins.m

#import "userPins.h"

@implementation userPins
@synthesize fbid = _fbid;
@synthesize coordinate = _coordinate;
@synthesize title = _title;
@synthesize subtitle = _subtitle;


- (id)initWithfbid:(NSInteger*)fbid 
        coordinate:(CLLocationCoordinate2D)coordinate {
    if ((self = [super init])) {
        _fbid = fbid;
        _coordinate = coordinate;
    }
    return self;
}


- (NSString *)subtitle{
    return @"Anything";
}
- (NSString *)title{
    return @"Something";
}

- (void)dealloc
{
    [_title release];
    [_subtitle release];
    [super dealloc];
}

@end

userPins.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface userPins : NSObject <MKAnnotation> {
    NSInteger *_fbid;
    CLLocationCoordinate2D _coordinate;
    NSString *_title;
    NSString *_subtitle;
}

@property (nonatomic, readonly) NSInteger *fbid;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
- (id)initWithfbid:(NSInteger*)fbid coordinate:(CLLocationCoordinate2D)coordinate;

@end

viewController.m

#import "lociseViewController.h"
#import "ASIHTTPRequest.h"
#import "SBJSON.h"
#import "userPins.h"

@implementation lociseViewController
@synthesize mapView = _mapView;


- (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.
}

#pragma mark - View lifecycle

// Add new method above refreshTapped
- (void)plotPositions:(NSString *)responseString {

    for (id<MKAnnotation> annotation in _mapView.annotations) {
        [_mapView removeAnnotation:annotation];
    }

    NSDictionary * root = [responseString JSONValue];
    NSArray *data = [root objectForKey:@"data"];
    for (NSArray * row in data) {
        NSInteger * fbid = (NSInteger *)[row objectAtIndex:0];
        NSNumber * latitude = [row objectAtIndex:1];
        NSNumber * longitude = [row objectAtIndex:2];

        CLLocationCoordinate2D coordinate;
        coordinate.latitude = latitude.doubleValue;
        coordinate.longitude = longitude.doubleValue;            
        userPins *annotation = [[[userPins alloc] initWithfbid:fbid coordinate:coordinate] autorelease];
        [_mapView addAnnotation:annotation];        
    }


}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    // 1
    MKCoordinateRegion mapRegion = [_mapView region];
    CLLocationCoordinate2D centerLocation = mapRegion.center;

    // 2
    NSString *jsonFile = [[NSBundle mainBundle] pathForResource:@"command" ofType:@"json"];

    NSString *formatString = [NSString stringWithContentsOfFile:jsonFile encoding:NSUTF8StringEncoding error:nil];
    NSString *json = [NSString stringWithFormat:formatString,                     centerLocation.latitude, centerLocation.longitude, 0.5*METERS_PER_MILE];


    NSURL *url = [NSURL URLWithString:@"http://localhost/users.json"];


    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    request.requestMethod = @"POST";  
    //request.defaultResponseEncoding = NSISOLatin1StringEncoding;
    //[request addRequestHeader:@"Content-Encoding" value:@"windows-1255"];
    [request addRequestHeader:@"Content-Type" value:@"application/json"];
    [request appendPostData:[json dataUsingEncoding:NSUTF8StringEncoding]];
    [request setDefaultResponseEncoding:NSUTF8StringEncoding];

    // 5
    [request setDelegate:self];
    [request setCompletionBlock:^{        
        NSString *responseString = [request responseString];
        NSLog(@"Response: %@", responseString);
        [self plotPositions:responseString];
    }];
    [request setFailedBlock:^{
        NSError *error = [request error];
        NSLog(@"Error: %@", error.localizedDescription);
    }];

    // 6
    [request startAsynchronous];
    //CLLocationManager *locationManager;
    //locationManager.delegate = self;

    [super viewDidLoad];

}


- (void)viewWillAppear:(BOOL)animated {  
    // 1
    CLLocationCoordinate2D zoomLocation;
    zoomLocation.latitude = 35.333070;
    zoomLocation.longitude = 33.302875;

    // 2
    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 50*METERS_PER_MILE, 3*METERS_PER_MILE);
    // 3
    MKCoordinateRegion adjustedRegion = [_mapView regionThatFits:viewRegion];                
    // 4

    [_mapView setRegion:adjustedRegion animated:YES];        
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView
{
    userPins *myAnnot = (userPins *)annotationView.annotation;
    [myAnnot setTitle:@"o21"];

    NSLog(@"Title: %@", annotationView.annotation.subtitle);

}


- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    static NSString *identifier = @"userPins";   
    if ([annotation isKindOfClass:[userPins class]]) {


        MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        } else {
            annotationView.annotation = annotation;
        }


        annotationView.image = [UIImage imageNamed:@"mapMarker-blue.png"];
        annotationView.calloutOffset = CGPointMake(0,0);

        UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        annotationView.rightCalloutAccessoryView = detailButton;


        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;

        return annotationView;

    }

    return nil;   

}



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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)dealloc {

    [_mapView release];
    [super dealloc];
}
@end

viewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

#define METERS_PER_MILE 1609.344

@interface lociseViewController : UIViewController <MKMapViewDelegate> {
    MKMapView *_mapView;
}

@property (nonatomic, retain) IBOutlet MKMapView *mapView;
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView;


@end

回答1:

The setTitle: and title methods in userPins.m don't look right.

The setTitle: method is looking at and setting subtitle instead of title. The title method returns a constant string so even if setTitle: set the title ivar, the annotation will return the same constant string.

You could fix those methods or just declare title and subtitle as copy properties and @synthesize them in userPins.m (and release in dealloc). Then you don't need those methods at all (they will be implemented automatically).

By the way, when you add the annotation, be sure to set the title to something (even a single space) otherwise the callout will not display and didSelectAnnotationView will not be called.

A separate problem is a memory leak in viewForAnnotation. You should add an autorelease where you alloc+init annotationView.


Regarding The Updated Code:

In userPins.m, it still returns constant strings for subtitle and title thus hiding the changed ivars. Change it to:

- (id)initWithfbid:(NSInteger*)fbid 
        coordinate:(CLLocationCoordinate2D)coordinate {
    if ((self = [super init])) {
        _fbid = fbid;
        _coordinate = coordinate;

        //init the ivars here...
        _title = @"Something";
        _subtitle = @"Anything";
    }
    return self;
}

/* comment these methods out
- (NSString *)subtitle{
    return @"Anything";
}
- (NSString *)title{
    return @"Something";
}
*/


A new, unrelated problem is that fbid should probably be NSNumber * instead of NSInteger *. NSInteger is not an object and an NSNumber is what the JSON parser is most likely giving you.