I am doing mapview. In my app there is code which gets current location of the user in latitude and longitude. Using this coordinates i am creating a soap request. In response i will get information(zip,city,state,country,coordinates) of locations. I have saved this information in NSDictionary.
This is the code for creating annotation.
MapLocation *annotation = [[MapLocation alloc] initWithCoordinate:location ownerInst:ownerInstitution];
[mapView addAnnotation:annotation];
[annotation release];
- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorGreen;
annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButton addTarget:self action:#selector(infoButtonPressed) forControlEvents:UIControlEventTouchUpInside];
annView.rightCalloutAccessoryView = infoButton;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
This is the delegate method when user tap the detaildisclosurebutton in the callout.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
On the tap of detail disclosure button new view will be loaded. And in this new view, information which i retrieved from the server will be displayed.
Upto this everything is fine. I have more than one annotations in the map. But when particular annotation is tapped how will i implement the code to show the information (which i get from the server)related to that annotation.
I hope I am clear in expressing my problem. Feel free to ask further details.
The MKAnnotationView *view which you get from the delegate method contains the Annotation. You can store all information in your MapLocation class you need to display.
MapLocation *annotation = [[MapLocation alloc] initWithCoordinate:location ownerInst:ownerInstitution];
[mapView addAnnotation:annotation];
[mapView addAdditionalCustomInformation: SomeInfo]; //you need to write your custom methods for that ;)
[annotation release];
Related
I have a map view and there are 10 store locations which data comes via webservice. I just want to push to my detail view to show address, telephone and other informations of the clicked store.
I need to pass data to my detailview when user tapped or touch up inside to a annotation on mapkit. There are 10 annotations in my mapview and first I want to know, how can I understand or how can I get the annotationID of which annotation is clicked?
this is the method I return pins
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]) return nil;
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
pinView.pinColor=MKPinAnnotationColorPurple;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
return pinView;
}
/* and my action method for clicked or tapped annotation: */
- (IBAction)showDetails:(id)sender{
NSLog(#"Annotation Click");
[[mtMap selectedAnnotations]objectAtIndex:0];
magazaDetayViewController *detail = [[magazaDetayViewController
alloc]initWithNibName:#"magazaDetayViewController" bundle:nil];
detail.sehir=#"";
detail.magazaAdi=#"";
detail.adres=#"";
detail.telefon=#"";
detail.fax=#"";
[self.navigationController pushViewController:detail animated:YES];
}
if i can just get the clicked annotation index no i can fill detail properties with my array.
if this is impossible is there any other way to do it?
First in your annotaion view delegat make a button to go in detail view like bellow:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"current"];
mypin.pinColor = MKPinAnnotationColorPurple;
mypin.backgroundColor = [UIColor clearColor];
UIButton *goToDetail = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
mypin.rightCalloutAccessoryView = myBtn;
mypin.draggable = NO;
mypin.highlighted = YES;
mypin.animatesDrop = TRUE;
mypin.canShowCallout = YES;
return mypin;
}
Now use the following delegate whenever the button in annotationView will get tapped the following delegate will be called from where you can easly get which particular annotaion's button is tapped
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
annotation *annView = view.annotation;
detailedViewOfList *detailView = [[detailedViewOfList alloc]init];
detailView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
detailView.address = annView.address;
detailView.phoneNumber = annView.phonenumber;
[self presentModalViewController:detailView animated:YES];
}
here annotaion is a class importing MKAnnotaion.h and address and phonenumber are properties of annotaion class you can make many more while the address and phoneNumber properties of detailView class are strong. So that you can pass values. Hope this will help you!
Bellow is Delegate method of MapView......
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
}
when user tap annotation pin above method call automaticaly if method define in .m file nut first declare MKMapViewDelegate delegate in .h file
and also you can get title or subtitle and id from google place API....
link is...
https://developers.google.com/maps/documentation/places/
for(int i=0; i<[arrLat count];i++) {
CLLocationCoordinate2D theCoordinate1;
konumpin* myAnnotation1=[[konumpin alloc] init];
theCoordinate1.latitude = [[arrLong objectAtIndex:i] doubleValue];
theCoordinate1.longitude = [[arrLat objectAtIndex:i] doubleValue];
myAnnotation1.coordinate=theCoordinate1;
myAnnotation1.title=[arrMagaza objectAtIndex:i];
[annotations addObject:myAnnotation1];
}
[mtMap addAnnotations:annotations];
I have a map with only one annotation.I created a simple class which I want it to show when the user clicks on the annotation.The problem is that when I click on the annotation nothing happens.
Here is my code:
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark{
NSLog(#"Reverse Geocoder completed");
mPlacemark=placemark;
[mapView addAnnotation:placemark];
}
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.animatesDrop=TRUE;
//create UIButton for annotation
UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//NSInteger annotationValue = [self.annotations indexOfObject:annotation];
[detailButton addTarget:self action:#selector(showDetailView:) forControlEvents:UIControlEventTouchUpInside];
annView.rightCalloutAccessoryView=detailButton;
return annView;
}
-(void)showDetailView:(id)sender{
NSLog("inside the stupid method");
MyDetailViewController *detailView=[[MyDetailViewController alloc] initWithNibName:#"MyDetailViewController" bundle:nil];
[[self navigationController] pushViewController:detailView animated:YES];
[detailView release];
}
My showDetailView function never gets called.Please help me.I'm new to iphone and I might forget a simple thing.Thanks
Still not working!!!!
First, check that the map view's delegate is set otherwise your viewForAnnotation method will not get called.
Next, the accessory button appears on the annotation's callout which will only appear if you set canShowCallout:
annView.canShowCallout = YES;
Next, instead of using your own method to handle the button action, it's much better to use the map view's own calloutAccessoryControlTapped delegate method which gets called when tapping an accessory:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"inside the stupid method");
//Here, the annotation tapped can be accessed using view.annotation
}
Remove the [detailButton addTarget... line from viewForAnnotation.
Also note your NSLog in the showDetailView method is missing the leading # which will result in a crash when the method does get called.
Another thing is you should use dequeueReusableAnnotationViewWithIdentifier in viewForAnnotation to enable annotation view re-use.
Example as requested:
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
static NSString *annReuseId = #"currentloc";
MKPinAnnotationView *annView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annReuseId];
if (annView == nil)
{
annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annReuseId];
annView.animatesDrop = YES;
annView.canShowCallout = YES;
UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annView.rightCalloutAccessoryView=detailButton;
}
else {
annView.annotation = annotation;
}
return annView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"calloutAccessoryControlTapped: annotation = %#", view.annotation);
MyDetailViewController *detailView=[[MyDetailViewController alloc] initWithNibName:#"MyDetailViewController" bundle:nil];
//here, can set annotation info in some property of detailView
[[self navigationController] pushViewController:detailView animated:YES];
[detailView release];
}
Ok. If you are using storyboards, you need to create a segue between the map view controller and then where the below code exists:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"calloutAccessoryControlTapped: annotation = %#", view.annotation);
MyDetailViewController *detailView=[[MyDetailViewController alloc] initWithNibName:#"MyDetailViewController" bundle:nil];
//here, can set annotation info in some property of detailView
[[self navigationController] pushViewController:detailView animated:YES];
[detailView release];
}
Use the following code instead:
NSLog(#"calloutAccessoryControlTapped: annotation = %#", view.annotation);
[self performSegueWithIdentifier:#"DetailViewController" sender:self];
This will give you the movement to the detailed view.
write your function like this:
-(IBAction)showDetailView:(id)sender{
NSLog("inside the stupid method");
MyDetailViewController *detailView=[[MyDetailViewController alloc] initWithNibName:#"MyDetailViewController" bundle:nil];
[[self navigationController] pushViewController:detailView animated:YES];
[detailView release];
}
you have to set the map delegate to self like this,
mapview.delegate=self; (if your calling the method in same page)
if you don't assign the delegate in your code the respective methods won't be called, so check if you have the above mentioned line.
Replace -(IBAction)showDetailView:(UIView*)sender with following...
-(void)showDetailView:(id)sender
I have went through a few links here, not all of them, regarding MKPinAnnotationView pin, subclass, etc. I did some simple tutorials online and when I thought I could start on my application with the knowledge from the tutorials, I was wrong. :(
In my tutorial file, I managed to do a simple MKPinAnnotationView *pin. Set its properties, like canShowCallOut = YES, draggable = YES. I can drag the pin anywhere I want to and display the location its dropped at.
But when I created my new application, I did the same thing again. But the pin isn't moving, is there something I did wrong?
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
if([annotation isKindOfClass:[CustomPlacemark class]])
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:[annotation title]];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES; // shows the black label when the pin is tapped
newAnnotation.draggable = YES;
// newAnnotation.enabled = YES;
newAnnotation.tag = tag;
NSLog(#"%# %#", [annotation title], [annotation subtitle]);
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
newAnnotation.rightCalloutAccessoryView = rightButton;
NSLog(#"Created annotation at: %f %f", ((CustomPlacemark*)annotation).coordinate.latitude, ((CustomPlacemark*)annotation).coordinate.longitude);
[newAnnotation addObserver:self
forKeyPath:#"selected"
options:NSKeyValueObservingOptionNew
context:#"GMAP_ANNOTATION_SELECTED"];
[newAnnotation autorelease];
tag++;
NSLog(#"ååååååååå %#", appDelegate.fml);
return newAnnotation;
}
return nil;
}
Take a look
http://digdog.tumblr.com/post/252784277/mapkit-annotation-drag-and-drop-with-callout-info
I'm looking for the same problem.
In my MapView i have pin dropped on certain locations and now i want to display some title on these pin annotation and make it clickable so that on click i can push another view.
Please help !!!!
This is the code snippet:
Custom Annotation View using this method
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
if (annotation == mapView.userLocation) return nil;
MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: #"asdf"];
if (pin == nil)
{
pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: #"asdf"] autorelease];
}
else
{
pin.annotation = annotation;
}
pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pin.pinColor = MKPinAnnotationColorRed;
pin.animatesDrop = YES;
[pin setEnabled:YES];
[pin setCanShowCallout:YES];
return pin;
}
Delegate method which get's called when you tap on the button
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//DetailPg=[[BookMarksDetail alloc]initWithNibName:#"BookMarksDetail" bundle:nil];
//DetailPg.selectRest =[view.annotation title]; //In addition, to get the Title of the AnnotationView.
//DetailPg.m=1;
//[self.navigationController pushViewController:DetailPg animated:YES];
//[DetailPg release];
}
The answers to this are all provided in Apples Docs I suggest you read them more closely. However to have a call out all you need to do is set the title property.
For buttons and such you need to use the MapView Delegate method:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
_pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
Apple suggests reusing annotations this is something you will need to take into account.
I got my map working fine with multiple annotations in an NSMuttableArray, MyAnnotations display fine with a title and subtitle and a rightcalloutbutton linked to a view with action #selector showDetails. However how do I load details for each annotation into that view? i.e if someone clicks empire state building it displays info about itself into that view, and someone clicks Chrysler building it also displays details about itself in this view.
I have been searching for ways for sometime however i cant seem to figure it out here is a snippet of my rootviewcontroller.m
if it helps all my annotations are named so on and so forth
[mapView addAnnotation:myAnnotation1];
[mapView addAnnotation:myAnnotation2];
[mapView addAnnotation:myAnnotation3];
[mapView addAnnotation:myAnnotation4];
with corresponding
MyAnnotation* myAnnotation1=[[MyAnnotation alloc] init];
myAnnotation1.coordinate=theCoordinate1;
myAnnotation1.title=#"Asda";
myAnnotation1.subtitle=#"Kimberley Way, TN240SE";
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"welcome into the map view annotation");
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// try to dequeue an existing pin view first
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
pinView.pinColor=MKPinAnnotationColorPurple;
//differnt colored pins based on title name
if ([[annotation title] isEqualToString:#"Asda"])
pinView.pinColor = MKPinAnnotationColorRed;
else if ([[annotation title] isEqualToString:#"Ashford Football Club"])
pinView.pinColor = MKPinAnnotationColorGreen;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"profile.png"]];
pinView.leftCalloutAccessoryView = profileIconView;
[profileIconView release];
return pinView;
}
-(IBAction)showDetails:(id)sender{
NSLog(#"Annotation Click");
self.userProfileVC.title=((UIButton*)sender).currentTitle;
[self.navigationController pushViewController:self.userProfileVC animated:YES];
}
- (void)dealloc {
[super dealloc];
}
#end
According to the documentation, your map's delegate should receive the message mapView:annotationView:calloutAccessoryControlTapped: when the button is tapped. This hands you the MKAnnotationView instance that was tapped, which has an annotation property to give you the corresponding annotation. You should make use of that instead of trying to use an action on the button directly.
You could do lik this.
CLLocationCoordinate2D location = [self addressLocation:address];
region.span=span;
region.center=location;
Annotation *addAnno= [[Annotation alloc] initWithCoordinate:location title:address subtitle:subaddres];
[annotations addObject:addAnno];
Therefore in Annotation you had delegate method title and subtitle-(NSSTring)title{, using this you can get your title and subtitle when you click appropriate Annotation.
in Annotation
-(id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString*)tit subtitle:(NSString*)sub{
mTitle=tit;
mSubTitle=sub;
return self;
}
I worked it out I declared a label in my detailsview class whick is called userProfileVC then used the below if statement to pass the information text to the correct label for each annotation.
-(IBAction)showDetails:(id)sender{
NSLog(#"Annotation Click");
self.userProfileVC.title=((UIButton*)sender).currentTitle;
if([((UIButton*)sender).currentTitle isEqualToString:#"Asda"])
self.userProfileVC.label.text= #"Glass, Paper, Cans, Textiles, Card, Shoes and Books";