show another view when clicked on pin annotation - objective-c

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).

Related

passing variable from MKAnnotationView to segue

I have an MKMapView, that I drop a number of pins on from an array. Each map pin has an MKAnnotationView that links to a segue and another controller.
All of this is working perfectly now, but I can't see how to pass a variable through the MKAnnotationView to the segue.
I can work with either passing a string or an integer, as I could pass a username as a string, or pass the id of the array and use that in the second view controller after the segue.
My working code for looping through my array, dropping the pins, adding the annotations, and then calling the segue is as below.
This all works fine, populates the map, drops the bins, and the annotations work and link to the new segue. This is all perfect!
I just need to be able to pass a variable through from the map pin array to the second view controller segue.
- (void)loadMapPins {
for (int i=0; i<maparray.count; i++){
Location *item = _feedItems1[i];
CLLocationCoordinate2D myCoordinate = {[item.latitude doubleValue], [item.longitude doubleValue]};
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = myCoordinate;
point.title = item.firstname;
point.subtitle = [NSString stringWithFormat: #"%#", item.username];
[self.mapView addAnnotation:point];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
if (annotation == self.mapView.userLocation) return nil;
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* customPin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
customPin.pinColor = MKPinAnnotationColorRed;
customPin.animatesDrop = YES;
customPin.canShowCallout = YES;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
customPin.rightCalloutAccessoryView = rightButton;
return customPin;
}
- (IBAction)showDetails:(id)sender {
[self performSegueWithIdentifier:#"showProfileFromMap" sender:self];
}
You should use this MKMapViewDelegate method
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
CustomAnnotationClass *annotation = view.annotation;
selectedAnnotationVariable = annotation.yourProperty;
[self performSegueWithIdentifier:#"performSegue" sender:self];
}

MKAnnotation looses title and subtitle when given a custom icon

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?

calloutAccessoryControlTabbed delegate does not get called

It doesn't give me any errors or warnings as well. I don't know what other relevant info or details I can provide. Please tell me if it's not enough.
_mapView.delegate is set to self
Method in which the calloutAccessoryControl is set:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
NSLog(#"Enter viewForAnnotation delegate");
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MapViewAnnotation class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
UIImageView *callOutButtonImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"arrow.png"]];
annotationView.rightCalloutAccessoryView = callOutButtonImage;
annotationView.image=[UIImage imageNamed:#"green-node.png"];
return annotationView;
}
return nil;
}
calloutAccessoryControlTabbed:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
NSLog(#"Control Tabbed!");
_scrollView.hidden = false;
}
The following is from the mapView:annotationView:calloutAccessoryControlTapped: discussion in the MKMapViewDelegate protocol reference document:
Accessory views contain custom content and are positioned on either side of the annotation title text. If a view you specify is a descendant of the UIControl class, the map view calls this method as a convenience whenever the user taps your view. You can use this method to respond to taps and perform any actions associated with that control. For example, if your control displayed additional information about the annotation, you could use this method to present a modal panel with that information.
I can see that you've added a UIImage to your annotation view's right callout accessory view. A UIImage object does not inherit from UIControl. A UIButton object would work.

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:].