MKPinAnnotationView draggable not working. draggable = YES, callout has title and subtitle, and setCoordinate is implemented - objective-c

When I try to drag the pin, it does not move. When I touch it, it darkens. However, it never lifts up, and it never moves around.
Here is the header file for my annotation class:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <Parse/Parse.h>
#interface GeoPointAnnotation : NSObject <MKAnnotation>
- (id)initWithObject:(PFObject *)aObject;
#property (nonatomic, readwrite, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, readonly, copy) NSString *title;
#property (nonatomic, readonly, copy) NSString *subtitle;
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate;
#end
Here's where I create the annotation in my view controller:
- (void)updateMap
{
[self.mapView removeAnnotations:self.mapView.annotations];
PFGeoPoint *geoPoint = [self.post location];
// center the map around the geopoint
[self.mapView setRegion:MKCoordinateRegionMake(
CLLocationCoordinate2DMake(geoPoint.latitude, geoPoint.longitude),
MKCoordinateSpanMake(0.01, 0.01)
)];
GeoPointAnnotation *annotation = [[GeoPointAnnotation alloc] initWithObject:self.post.object];
[self.mapView addAnnotation:annotation];
}
// from Geolocations by Parse
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
static NSString *GeoPointAnnotationIdentifier = #"RedPin";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:GeoPointAnnotationIdentifier];
if (!annotationView) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:GeoPointAnnotationIdentifier];
annotationView.pinColor = MKPinAnnotationColorRed;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
annotationView.animatesDrop = YES;
}
return annotationView;
}
Any ideas?

Found the problem: I forgot to hook up the Map View's delegate in my Storyboard xib. h/t Nitin Gohel - thanks!

Related

Xcode: Passing an object between two views?

I have eventually succeeded with getting the index for the annotation clicked on at callOutAccecoryControlTapped-method. :)
I have made a custom annotation class called Annotation (Annnotation *ann) which I fill with values from my db at parse.com.
But now I don't know how to pass the values on to my next view LAOpeningHoursViewController?
I can see all the values when I am debugging and *ann (se code) has for example: ann.cname="Olles cafe" etc. So that is good.
I pass the whole ann-object on to my next view. But I don't know how to get for example ann.cname on to my 'self.myLabel.text'. I show you the code:
If you have the kindness to answer me, please explain very well because I am a beginner.
Best is if you could have the trouble writing a code-snippet here… ;)
This is some code of the first view:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"];
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:(UIControl *)control {
Annotation *ann = [[mapView selectedAnnotations] objectAtIndex:0];
NSLog(#"ann.subtitle = %#", ann.subtitle);
NSLog(#"ann.cid = %#", ann.cid);
NSLog(#"ann.cstr = %#", ann.cstr);
NSLog(#"ann.cname = %#", ann.cname);
//this works fine, I get all the values
[self performSegueWithIdentifier: #"openingHours" sender:ann];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"openingHours"]) {
LAOpeningHoursViewController *secondView = (LAOpeningHoursViewController*)segue.destinationViewController;
//PFObject *tempObject = [[myMapView selectedAnnotations] objectAtIndex:0];
Annotation *ann = (id)sender;
//Here is the problem: What to pass? I want to pass for example ann.cname that is declared in my custom annotation
//Both 'ann' and 'tempObject' has the right values for cname but I dont know how to pass it to the next view
secondView.myLabel.text = self.stringToPass;
//secondView.myLabel.text = ann.cname;
}
}
And here is the code from the second view called LAOpeningHoursViewController, that should receive the data:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myLabel.text = ann.cname;
//recieving an error-code… of course
}
declared in LAOpeningHoursViewController.h as this
#property (strong, nonatomic) IBOutlet UILabel *myLabel;
#property (strong, nonatomic) NSString *textContent;
and finally, here is my Annotation.h-file where cname is the one that should go to 'myLabel'
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property(nonatomic, assign) CLLocationCoordinate2D coordinate;
#property(nonatomic, copy)NSString *title;
#property(nonatomic, copy)NSString *subtitle;
#property(nonatomic, copy)UIButton *rightButton;
#property(nonatomic, retain)NSString *cid;
#property(nonatomic, retain)NSString *cname;
#property(nonatomic, retain)NSString *ctel;
#property(nonatomic, retain)NSString *cstr;
#property(nonatomic, retain)NSString *cmon;
#property(nonatomic, retain)NSString *ctue;
#property(nonatomic, retain)NSString *cwed;
#property(nonatomic, retain)NSString *passedId;
#property(nonatomic, retain)NSString *objectId;
#end
The sender parameter in [self performSegueWithIdentifier: #"openingHours" sender:ann]; should be set to self. This is intended to give the presented view controller reference to the presenting controller.
Add the property #property (nonatomic, strong) Annotation *selectedAnnotation to the presenting view controller. So that it can be set thus:
//this works fine, I get all the values
[self setSelectedAnnotation:ann];
[self performSegueWithIdentifier: #"openingHours" sender:ann];
Now you have the selected annotation as a property it can be used to initialize the LAOpeningHoursViewController:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"openingHours"]) {
LAOpeningHoursViewController *secondView = (LAOpeningHoursViewController*)segue.destinationViewController;
//PFObject *tempObject = [[myMapView selectedAnnotations] objectAtIndex:0];
Annotation *ann = (id)sender;
// Setup second view here:
secondView.myLabel.text = self.selectedAnnotation.cname;
// assign further properties here...
}
}
I hope this helps, good luck!

Not getting the proper map using MKMapVIew

I have created a mapview using MKMapView. Everything is working fine but there is a difference in the map which i am getting and which i was supposed to get. In my view map is coming but not properly i guess. please see the difference and let me know what is the problem .
thanks
Here's my ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
mapView=[[MKMapView alloc]initWithFrame:CGRectMake(0, 0, 320, 400)];
mapView.delegate=self;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
MKCoordinateRegion region = { {0.0, 0.0},{0.0,0.0}};
region.center.latitude = 12.9667;
region.center.longitude = 77.5833;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[mapView setRegion:region animated:YES];
[self.view addSubview:mapView];
DisplayMap *annotation = [[DisplayMap alloc]init];
annotation.title = #" Bangalore";
annotation.subtitle = #"Silver Jublee Park";
annotation.coordinate = region.center;
[mapView addAnnotation:annotation];
}
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:
(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ) pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
}
return pinView;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
#implementation DisplayMap
#synthesize coordinate,title,subtitle;
-(void)dealloc{
[title release];
[subtitle release];
[super dealloc];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController<MKMapViewDelegate> {
MKMapView *mapView;
}
#end
#class DisplayMap;
#interface DisplayMap : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end
I am getting the following map
I should get the following map
When I put the coordinates you're using into Google Maps I go to the same place that you are seeing, not the place you think you "should" be getting. Have you verified the coordinates? What are the coordinates of the lace you think you should be going to?
Here's a route between the two place http://goo.gl/maps/TrM3q
According to Goolge you are expecting iOS to should a place ~2000km away from the coordiantes you are using, which ain't gonna happen.

checking which map view annotation is tapped on mkmapview

I am having problem in knowing which annotation is tapped on MKMapView.
let me explain my problem, there is a simple view controller on which map view is loaded.
my annotation class "MapViewAnnotation.h" is as follows
#interface MapViewAnnotation : NSObject <MKAnnotation>
{
NSString *title;
CLLocationCoordinate2D coordinate;
NSString *sID;
NSString *zipCode;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, retain) NSString *sID;
#property (nonatomic, retain) NSString *zipCode;
- (id)initWithTitle:(NSString *)titleOfPin andStoreId:(NSString *)storeIdForDetails andCoordinate:(CLLocationCoordinate2D)coordinateOfPin andZipCode:(NSString *)zip;
here is my "MapViewAnnotation.m" file.
#import "MapViewAnnotation.h"
#import <MapKit/MapKit.h>
#implementation MapViewAnnotation
#synthesize title, coordinate,storeId,zipCode;
- (id)initWithTitle:(NSString *)titleOfPin andStoreId:(NSString *)storeIdForDetails andCoordinate:(CLLocationCoordinate2D)coordinateOfPin andZipCode:(NSString *)zip
{
[super init];
title = titleOfPin;
coordinate = coordinateOfPin;
sID = storeIdForDetails;
zipCode = zip;
return self;
}
-(void)dealloc
{
[title release];
[super dealloc];
}
#end
and this is my viewcontroller.m file
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//I want to access the sID property of that annotation here. PLEASE HELP ME HOW CAN I DO THAT
if (!storeDetailControllerObject) {
storeDetailControllerObject = [[StoreDetailController alloc]init];
}
// storeDetailControllerObject.storeId = [view.annotation storeId];
[self.navigationController pushViewController:storeDetailControllerObject animated:YES];
From the MKMapViewDelegate protocol reference:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view;
If you handle the event in this method you may know which annotation was selected.
You have to set the MKMapView's delegate and to declare that you class implements the MKMapViewDelegate.
This should work:
MapViewAnnotation *mapViewAnnotation = (MapViewAnnotation*)view.annotation;
if( [mapViewAnnotation isKindOfClass:[MapViewAnnotation class]] ){
storeDetailControllerObject.storeId = mapViewAnnotation.storeId;
}

iOS mapview - trouble when adding annotations

Trying to add some annotations for a MapView, but keep getting an ARC Semantic issue: 'No visible #interface for 'MKPointAnnotation' declares the selector initWithTitle:andCoordinate:
I'm fairly new to this so don't really know what it means, if anyone could explain/correct it i'd be grateful.
Here is my viewDidLoad method:
- (void)viewDidLoad
{
CLLocationCoordinate2D location;
location.latitude = (double) 51.501468;
location.longitude = (double) -0.141596;
MKPointAnnotation *newAnnotation = [[MKPointAnnotation alloc] initWithTitle:#"Buckingham Palace" andCoordinate:location];
[self._mapView addAnnotation:newAnnotation];
}
and my header file:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MapViewAnnotation : NSObject <MKAnnotation> {
NSString *title;
CLLocationCoordinate2D coordinate;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;
#end
The initWithTitle:andCoordinate method you created is a method of MapViewAnnotation rather than MKPointAnnotation.
You probably want:
MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"Buckingham Palace" andCoordinate:location];
[self._mapView addAnnotation:newAnnotation];
It's trying to tell you it can't find any method that matches the signature of initWithTitle:andCoordinate:
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:coordinate];
[annotation setTitle:#"Buckingham Palace"];

selectAnnotation does not show callout

I want to change the callout shown on the MKMapView. When I call
[self.mapView selectAnnotation:annotation animated:YES];
it pans the map to the annotation, but does not show its callout. How do I get it to show the callout?
Set the title, and optionally the subtitle property on the annotation object. MapKit will automatically show a callout.
#interface MyAnnotation : NSObject <MKAnnotation> {
NSString *title;
NSString *subtitle;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end
And the implementation,
#import "MyAnnotation.h"
#implementation MyAnnotation
#synthesize title, subtitle;
#end
Usage,
MyAnnotation *foo = [[MyAnnotation alloc] init];
foo.title = #"I am Foo";
foo.subtitle = "I am jus' a subtitle";
You should implement the MKAnnotation Delegate method
-(MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *AnnotationViewIdentifier = #"AnnotationViewIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewIdentifier];
if (annotationView == nil)
{
annotationView = [[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:AnnotationViewIdentifier]autorelease];
}
annotationView.canShowCallout = YES;
return annotationView;
}