MKAnnotation looses title and subtitle when given a custom icon - objective-c

Ok so I am making an iOS application using the MapKit framework. I have got the functionality working but am now having trouble when changing the icon of the annotation. I can change the annotations icon but when I do so the annotation looses it's title and subtitle values (nothing pops up when tapped). I think maybe the issue is due to something like not giving the annotation an identifier when first made but I am not sure...
If anyone could let me know whats going on it would be greatly appreciated!
The code to add annotation is:
-(void)addAnnotationAtLattitude:(double)lattitude withLongitude:(double)longitude withTitle:(NSString *)title withSubtitle:(NSString *)subtitle{
//Handles the adding off the anotation
CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = lattitude;
annotationCoord.longitude = longitude;
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = title;
annotationPoint.subtitle = subtitle;
[self.MessageMap addAnnotation:annotationPoint];
}
and the code to change the icon (via delegate method ) is:
-(MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id
<MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationViewID];
}
annotationView.image = [UIImage imageNamed:#"CustomMapAnnotationIcon"];//mycustom image
annotationView.annotation = annotation;
return annotationView;
}

Are annotationView.enabled and annotationView.canShowCallout set to YES?

Related

show another view when clicked on pin annotation

I have many garages and need to show multiple garages in map.
Below is the code I am using for Map to show multiple pins.
CLLocationCoordinate2D annotationCoord;
for (NSMutableDictionary* aDict in Gfeeds) {
annotationCoord.latitude = [aDict[#"GLatitude"] floatValue];
annotationCoord.longitude = [aDict[#"GLongitude"] floatValue];
MKPointAnnotation *annotationPoint2 = [[MKPointAnnotation alloc] init];
annotationPoint2.coordinate = annotationCoord;
annotationPoint2.title = [NSString stringWithFormat:#"%#", aDict[#"GName"]];
annotationPoint2.subtitle = aDict[#"GId"];
[geomapView addAnnotation:annotationPoint2];
}
Now what I wanted is show the details of garage after clicking that map pin… for that I am doing below.
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
MKPinAnnotationView *pinAnnotation = nil;
if(annotation != geomapView.userLocation)
{
static NSString *defaultPinID = #"myPin";
pinAnnotation = (MKPinAnnotationView *)[geomapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinAnnotation == nil )
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinAnnotation.canShowCallout = YES;
//instatiate a detail-disclosure button and set it to appear on right side of annotation
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotation.rightCalloutAccessoryView = infoButton;
}
return pinAnnotation;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
GarageDetailsViewController *secondView = [self.storyboard instantiateViewControllerWithIdentifier:#"GarageDetails"];
secondView.garageMainId = view.annotation.subtitle;
[self.navigationController pushViewController:secondView animated:YES];
}
Using this way I can able to go to GarageDetails, however risk I am taking is showing Id of garage in subtitle. I want to hide this subtitle so that Id would not get displayed.
Any idea how can I do this?
Hide subtitle
OR
Pass id to GarageDetails from map...
Why not subclass "MKPointAnnotation" (you can name it something like "FahimPointAnnotation), and in this subclass you can add a "garageID" property.
Then you can add the annotation to your map and when it's clicked on, you can retrieve the annotation and cast the "MKPointAnnotation" back to a "FahimPointAnnotation" and grab your garageID out of it (without having to worry about it appearing in the annotation view's subtitle field).

Custom image for annotation pin in mkmapview

Custom annotation pin changes to default red pin at long tap.
- (MKAnnotationView *) mapView:(MKMapView *)mapingView viewForAnnotation:(id <MKAnnotation>) annotation {
MKPinAnnotationView *annView = nil;
if(annotation != mapingView.userLocation)
{
static NSString *defaultPinID = kDEFAULTPINID;
annView = (MKPinAnnotationView *)[mapingView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( annView == nil )
annView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID] ;
annView.canShowCallout = YES;
annView.image = [UIImage imageNamed:#"icon.png"];//sets image for default pin
}
return annView;
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKPinAnnotationView *)view
{
if ([[view.annotation title] isEqualToString:#"AnnotationTitle"] ) {
view.image = [UIImage imageNamed:#"selected_IconImage.png"];
}
}
Just touching the annotation pin the selected image appears.
But on long tap on the pin custom image reverts to default red pin.
How to fix this issue?
Use an MKAnnotationView instead of an MKPinAnnotationView, I'm guessing the map view performs some sort of reset, which goes back to the default image (which is the pin image you see)

iOS 5 custom annotation not showing its title

I wrote this code to create a custom annotation image
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *google = #"googlePin";
if ([annotation isKindOfClass:[myClass class]])
{
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:google];
if (!annotationView)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:google];
annotationView.image = [UIImage imageNamed:#"pin.png"];
}
return annotationView;
}
return nil;
}
The image is appearing on the map; however when I click on it nothing happen, no title nor subtitle.
Do you guys have any idea?
When you override viewForAnnotation, you have to set canShowCallout to YES (the default on a new view you alloc/init is NO).
If you don't override that delegate method, the map view creates a default red pin with canShowCallout already set to YES.
However, even with canShowCallout set to YES, the callout will still not appear if the annotation's title is nil or blank (empty string).
(But again, if the title is not nil and not blank, the callout won't show unless canShowCallout is YES.)
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:google];
if (!annotationView)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:google];
annotationView.image = [UIImage imageNamed:#"pin.png"];
annotationView.canShowCallout = YES; // <-- add this
}
else
{
// unrelated but should handle view re-use...
annotationView.annotation = annotation;
}
return annotationView;

Mapview application withh different icons in Iphone

Please some body give me some idea I am new on mapview application.
I need to display a map, when my app get loaded its will display a map in this map it will display some icons that icon must be dynamically and must be perform some action as we consider we have to display dynamically button on map view and perform different action with this button.
like if 5 icons come from server it will display 5 icons in map (icon must be dynamically come from server and display in google map.).
you can use the MKPlacemark as a "button"
first get location from server
- (void)addAnnotations:(CLLocationCoordinate2D)coordinate {
// Pin 1
CLLocationCoordinate2D coordinate1 = {
x.x, y.y
};
NSDictionary *address = [NSDictionary dictionaryWithObjectsAndKeys:#"Pin 1", #"Country", #"1", #"Thoroughfare", nil];
MKPlacemark *pin = [[MKPlacemark alloc] initWithCoordinate:coordinate1 addressDictionary:address];
[mapView addAnnotation:pin];
set its callout as a button to perform some action
- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation
{
MKPlacemark *placemark = annotation;
MKPinAnnotationView *pin = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier: #"asdf"];
if (pin == nil)
{
pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: #"asdf"] autorelease];
}
else
{
pin.annotation = annotation;
}
pin.canShowCallout = YES;
pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
also set the pins image to whatever you like, so the pin looks like a button
pin.image = [UIImage imageNamed:#"some-pic.png"];
and tell it what to do
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;{
//code whatever should be done

Showing the Pin Information by Default

I am working with MKPinAnnotationView annotations pins over a MKMapView. Into the view that I am developing, there is a map centered on a pin. When I call the view the pin drops down and if I make a click over it, it shows the annotation information (canShowCallout = YES). How I can get this callout just when I open the view? Without making a click over the annotation pin.
Thanks for reading.
Edited:
I am using this code.
- (void)viewDidLoad {
[super viewDidLoad];
AddressAnnotation *annotation = [[[AddressAnnotation alloc] initWithCoordinate:self.currentAnnotationCoordinate] autorelease];
[self.mapView addAnnotation:annotation];
[self zoomCoordinate:self.currentAnnotationCoordinate];
}
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation {
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
else { // Handles the other annotations.
// Try to dequeue an existing pin view first.
static NSString *AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView) {
// If an existing pin view was not available, creates one.
MKPinAnnotationView *customPinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
// Adds a detail disclosure button.
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;
} else
pinView.annotation = annotation;
}
return nil;
}
- (void)mapViewDidFinishLoadingMap:(MKMapView *)theMapView {
AddressAnnotation *annotation = [[[AddressAnnotation alloc] initWithCoordinate:self.currentAnnotationCoordinate] autorelease];
for (id<MKAnnotation> currentAnnotation in mapView.annotations) {
if ([currentAnnotation isEqual:annotation]) {
[mapView selectAnnotation:currentAnnotation animated:FALSE];
}
}
}
Edited:
Calling didAddAnnotationViews: instead of mapViewDidFinishLoadingMap: (as aBitObvious has commented), it works fine.
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
id<MKAnnotation> myAnnotation = [self.mapView.annotations objectAtIndex:0];
[self.mapView selectAnnotation:myAnnotation animated:YES];
}
Possible duplicate: How to trigger MKAnnotationView's callout view without touching the pin?
You want to call [mapView selectAnnotation:].