- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
NSLog(#"I'm Working");
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[userPins class]]) {
userPins *location = (userPins *) annotation;
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;
if ([location.name compare:#"LARCENY"] == NSOrderedSame) {
annotationView.pinColor = MKPinAnnotationColorGreen;
}
return annotationView;
}
return nil;
}
This code not working. I'm adding pins from JSON. I see red pins but I can't see nslog(I'm working). Any ideas?
You need to set the mapView's delegate in viewDidLoad or in the nib or wherever you are creating it.
Related
Hope someone can help, I'm trying to implement dropping one single Pin on a mapView. But I want the pin to be able to be dragged around and and dropped and for this annotation to be separate from the annotation for the user's location. Whilst the below code works, it creates duplicate pins for a user's touch and the pins can not be dragged around:
- (void)dropPinFromPress:(UIGestureRecognizer *)recognizer {
// Add Pin from User's Touch
if (recognizer.state != UIGestureRecognizerStateBegan) {
return;
}
// convert touched position to map coordinate
CGPoint userTouch = [recognizer locationInView:self.mapView];
CLLocationCoordinate2D mapPoint = [self.mapView convertPoint:userTouch toCoordinateFromView:self.mapView];
// Add Pin from user's touch
Annotation *pin = [[Annotation alloc]initWithLocation:mapPoint];
[self.mapView addAnnotation:pin];
}
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
MKAnnotationView *a = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
// a.title = #"test";
if ( a == nil )
a = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier: #"currentloc" ];
NSLog(#"%f",a.annotation.coordinate.latitude);
NSLog(#"%f",a.annotation.coordinate.longitude);
CLLocation* currentLocationMap = [[[CLLocation alloc] initWithLatitude:a.annotation.coordinate.latitude longitude:a.annotation.coordinate.longitude] autorelease];
[self coordinatesToDMS:currentLocationMap];
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:a reuseIdentifier:#"currentloc"];
if(a.annotation.coordinate.longitude == mapView.userLocation.coordinate.longitude || a.annotation.coordinate.latitude == mapView.userLocation.coordinate.latitude )
{
if ([annotation isKindOfClass:MKUserLocation.class])
{
//user location view is being requested,
//return nil so it uses the default which is a blue dot...
return nil;
}
//a.image = [UIImage imageNamed:#"userlocation.png"];
//a.pinColor=[UIColor redColor];
}
else
{
// annView.image =[UIImage imageNamed:#"map-pin.png"];
//PinFirst=FALSE;
//annView.pinColor = [UIColor redColor];
// annView.annotation=annotation;
}
annView.animatesDrop = YES;
annView.draggable = YES;
annView.canShowCallout = YES;
return annView;
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(#"map Drag");
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState;
{
NSLog(#"pin Drag");
if (newState == MKAnnotationViewDragStateEnding)
{
CLLocationCoordinate2D droppedAt = view.annotation.coordinate;
NSLog(#"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude);
CLLocation* draglocation = [[[CLLocation alloc] initWithLatitude:droppedAt.latitude longitude:droppedAt.longitude] autorelease];
}
}
I am working on an mapkit app which drops pins on the map on certain locations (code at the end)
I have also added code for the callout. However, depending on which pin was tapped I was attemping to load a different views and I have no found any way to do oddly.
I placed a breakpoint and while stepping thru I noticed that there was a line which read.
"annotation.title=#"myhome"; so i was wondering if there way someway i could say what to call depending on which annotation was tapped.
Thanks
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *identifier = #"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.pinColor = MKPinAnnotationColorRed;
annotationView.animatesDrop = YES;
annotationView.canShowCallout = YES;
}else {
annotationView.annotation = annotation;
}
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
NSLog(#"Callout Tapped");
}
--Updated Code
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// NSLog(annotation);
static NSString *identifier = #"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.pinColor = MKPinAnnotationColorRed;
annotationView.animatesDrop = YES;
annotationView.canShowCallout = YES;
}else {
annotationView.annotation = annotation;
}
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
id <MKAnnotation> annotation = [view annotation];
if ([annotation isKindOfClass:[MKPointAnnotation class]])
{
// MKUserLocation *ann = (MKUserLocation *)view.annotation;
// NSLog(#"ann.title = %#", ann.title);
NSLog(#"HJ");
}
}
You could set tags say 1 for left and 2 for right accessory view. And in your calloutAccessoryControlTapped method, do like:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
if ([control tag] == 1) {
NSLog(#"tapped left accessory");
}
else if ([control tag] == 2) {
NSLog(#"tapped right accessory");
}
}
We are trying to implement MKMapView in iOS application.I got the mapView with the given locations and pins.When I tap on these pins I am getting the title and subtitle also.Now I want to include a detail Disclosure button in this view in which the title and subtitle are displayed.For that I used the below given code[MKPinannotation detail disclosure button - present new view is going inside the first method but it is not showing the detailDisclosureButton.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"] autorelease];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
} else {
pinView.annotation = annotation;
}
return pinView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped
{
}
Now what can I do?Anyone please take a look and help me...
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation {
pinView = nil;
if(annotation != map.userLocation)
{
NSString *defaultPinID =#"com.invasivecode.pin1";
pinView = (MKPinAnnotationView *)[map dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ) pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
UIButton *btnGo = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[btnGo addTarget:self action:#selector(goToLocation:) forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView=btnGo;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
pinView.draggable=NO;
}
else {
[map.userLocation setTitle:#"I am here"];
}
return pinView;
}
Declare this in .h file
MKPinAnnotationView *pinView
please try setting the frame for rightButton i.e
rightButton.frame = CGRectMAke (x,y,width,height);
I have latitude and long values and I need to be able to drop a pin at this location.
Can anybody provide some advice on how to go about this?
Find the below very simple solution to drop the pin at given location define by CLLocationCoordinate2D
Drop Pin on MKMapView
Edited:
CLLocationCoordinate2D ctrpoint;
ctrpoint.latitude = 53.58448;
ctrpoint.longitude =-8.93772;
AddressAnnotation *addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:ctrpoint];
[mapview addAnnotation:addAnnotation];
[addAnnotation release];
You should:
1. add the MapKit framework to your project.
2. create a class which implements the MKAnnotation protocol.
Sample:
Annotation.h
#interface Annotation : NSObject <MKAnnotation> {
NSString *_title;
NSString *_subtitle;
CLLocationCoordinate2D _coordinate;
}
// Getters and setters
- (void)setTitle:(NSString *)title;
- (void)setSubtitle:(NSString *)subtitle;
#end
Annotation.m
#implementation Annotation
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[self setTitle:nil];
[self setSubtitle:nil];
[super dealloc];
}
#pragma mark -
#pragma mark Getters and setters
- (NSString *)title {
return _title;
}
- (NSString *)subtitle {
return _subtitle;
}
- (void)setTitle:(NSString *)title {
if (_title != title) {
[_title release];
_title = [title retain];
}
}
- (void)setSubtitle:(NSString *)subtitle {
if (_subtitle != subtitle) {
[_subtitle release];
_subtitle = [subtitle retain];
}
}
- (CLLocationCoordinate2D)coordinate {
return _coordinate;
}
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
_coordinate = newCoordinate;
}
#end
2. create an instance of this class and set the lat/lon property
3. add the instance to the MKMapView object with this method:
- (void)addAnnotation:(id<MKAnnotation>)annotation
4. You should set the delegate of the map and implement the following method:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString* ShopAnnotationIdentifier = #"shopAnnotationIdentifier";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ShopAnnotationIdentifier];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ShopAnnotationIdentifier] autorelease];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
}
return pinView;
}
This assumes that you have ARC enabled and that you have included the MapKit framework.
First create a class that implements the MKAnnotation protocol. We'll call it MapPinAnnotation.
MapPinAnnotation.h
#interface MapPinAnnotation : NSObject <MKAnnotation>
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, readonly) NSString* title;
#property (nonatomic, readonly) NSString* subtitle;
- (id)initWithCoordinates:(CLLocationCoordinate2D)location
placeName:(NSString *)placeName
description:(NSString *)description;
#end
MapPinAnnotation.m
#implementation MapPinAnnotation
#synthesize coordinate;
#synthesize title;
#synthesize subtitle;
- (id)initWithCoordinates:(CLLocationCoordinate2D)location
placeName:(NSString *)placeName
description:(NSString *)description;
{
self = [super init];
if (self)
{
coordinate = location;
title = placeName;
subtitle = description;
}
return self;
}
#end
Then add the annotation to the map using the following:
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(34.421496,
-119.70182);
MapPinAnnotation* pinAnnotation =
[[MapPinAnnotation alloc] initWithCoordinates:coordinate
placeName:nil
description:nil];
[mMapView addAnnotation:pinAnnotation];
The containing class will have to implement the MKMapViewDelegate protocol. In particular you will have to define the following function to draw the pin:
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
static NSString* myIdentifier = #"myIndentifier";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:myIdentifier];
if (!pinView)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:myIdentifier];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = NO;
}
return pinView;
}
In this example the MKAnnotation title and subtitle member variables are not used, but they can be displayed in the delegate function.
-(MKPointAnnotation *)showClusterPoint:(CLLocationCoordinate2D)coords withPos:(NSString *)place
{
float zoomLevel = 0.5;
region = MKCoordinateRegionMake (coords, MKCoordinateSpanMake (zoomLevel, zoomLevel));
[mapView setRegion: [mapView regionThatFits: region] animated: YES];
point = [[MKPointAnnotation alloc]init];
point.coordinate = coords;
point.title=place;
[mapView addAnnotation:point];
return point;
}
Swift Version
let location = CLLocationCoordinate2DMake(13.724362, 100.515342);
let region = MKCoordinateRegionMakeWithDistance(location, 500.0, 700.0)
self.mkMapView.setRegion(region, animated: true)
// Drop a pin
let dropPin = MKPointAnnotation();
dropPin.coordinate = location;
dropPin.title = "Le Normandie Restaurant";
self.mkMapView.addAnnotation(dropPin);
Please use this code. its working fine.
-(void)addAllPinsOnMapView
{
MKCoordinateRegion region = mapViewOffer.region;
region.center = CLLocationCoordinate2DMake(23.0225, 72.5714);
region.span.longitudeDelta= 0.1f;
region.span.latitudeDelta= 0.1f;
[mapViewOffer setRegion:region animated:YES];
mapViewOffer.delegate=self;
MKPointAnnotation *mapPin = [[MKPointAnnotation alloc] init];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(23.0225, 72.5714);
mapPin.title = #"Title";
mapPin.coordinate = coordinate;
[mapViewOffer addAnnotation:mapPin];
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:
(MKAnnotationView *)view
{
NSLog(#"%#",view.annotation.title);
NSLog(#"%f",view.annotation.coordinate.latitude);
NSLog(#"%f",view.annotation.coordinate.longitude);
}
- (MKAnnotationView *)mapView:(MKMapView *)theMapView
viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
((MKUserLocation *)annotation).title = #"Current Location";
return nil;
}
else
{
MKAnnotationView *pinView = nil;
static NSString *defaultPinID = #"annotationViewID";
pinView = (MKAnnotationView *)[mapViewOffer dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ){
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
}
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"placeholder"];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
// [infoButton addTarget:self action:#selector(infoButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = infoButton;
pinView.rightCalloutAccessoryView.tag=1;
return pinView;
}
}
- (MKPinAnnotationView*)myMap:(MKMapView*)myMap viewForAnnotation:
(id<MKAnnotation>)annotation{
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"CustomPin"];
UIImage *icon = [UIImage imageNamed:#"bustour.png"];
UIImageView *iconView = [[UIImageView alloc] initWithFrame:CGRectMake(8,0,32,37)];
if(icon == nil)
NSLog(#"image: ");
else
NSLog(#"image: %#", (NSString*)icon.description);
[iconView setImage:icon];
[pin addSubview:iconView];
pin.canShowCallout = YES;
pin.pinColor = MKPinAnnotationColorPurple;
return pin;
}
- (IBAction)btnLocateMe:(UIButton *)sender
{
[mapViewOffer setCenterCoordinate:mapViewOffer.userLocation.location.coordinate animated:YES];
}
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:].