Set size of annotation icon in MKMapView - iOS - ios

I am trying to display some icons on a MKMapView. I have achieved that by using this code:
MapPoint *placeObject = [[MapPoint alloc] initWithName:place.name
address:place.address
coordinate:place.location.coordinate
image:place.customMapPinImage
icon:place.icon
bookmark:place.bookmark
contents_ID:place.contents_ID
contents_lang_MAIN_ID:place.contents_lang_MAIN_ID
contents_lang_ID_ML:place.contents_lang_ID_ML];
[mapView addAnnotation:placeObject];
The problem is that, without changing anything in the code, the size of the icons changed and I don't know why. How can I adjust the size of the icons?

You need to write class annotations
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic) CLLocationCoordinate2D coordinate;
#property (strong, nonatomic) NSString *myTitle;
+ (Annotation *)initAnnotation:(CLLocationCoordinate2D)coordinate title:(NSString *)title;
#end
Implementation
#import "Annotation.h"
#implementation Annotation
+ (Annotation *)initAnnotation:(CLLocationCoordinate2D)coordinate title:(NSString *)title
{
return [[Annotation alloc] initWithAnnotation:coordinate title:title];
}
- (instancetype)initWithAnnotation:(CLLocationCoordinate2D)coordinate title:(NSString *)title
{
self = [super init];
self.coordinate = coordinate;
self.myTitle = title;
return self;
}
#end
ViewController
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "Annotation.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//set coordinates
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(51.50851, -0.02172);
//add annotation
Annotation *annotation = [Annotation initAnnotation:coordinate title:#"Annotation"];
[self.mapView addAnnotation:annotation];
[self.mapView showAnnotations:#[annotation] animated:YES];
// add circle with radius
MKCircle *circle = [MKCircle circleWithCenterCoordinate:annotation.coordinate radius:10000];
[self.mapView addOverlay:circle];
//add region by coordinates
MKCoordinateRegion region;
region.center.latitude = 51.50851;
region.center.longitude = -0.02172;
// level zoom
region.span.latitudeDelta = 1;
region.span.longitudeDelta = 1;
region = [self.mapView regionThatFits:region];
[self.mapView setRegion:region animated:YES];
}
Do not forget to set the controller as a map delegate, and implement the circle mapping method
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>) overlay{
MKCircleRenderer *circleView = [[MKCircleRenderer alloc] initWithOverlay:overlay];
circleView.fillColor = [[UIColor greenColor] colorWithAlphaComponent:0.4];
return circleView;
}[![enter image description here][1]][1]
Pin appears, and you can adjust its size
https://prntscr.com/lvfjwi

Related

UISearchBar not working even with delegate set in viewDidLoad

The searchBarBookmarkButtonClicked method isn't firing when I tap on the search bar. I have already added the self.searchBar.deleagate = self; and in my .h file I added the <UISearchBarDelegate>.
.h file:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController <UISearchBarDelegate,MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
#property (strong, nonatomic) IBOutlet MKMapView *myMap;
#end
.m file:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.searchBar.delegate = self;
self.myMap.delegate = self;
}
- (void)searchBarBookmarkButtonClicked:(UISearchBar * )searchBar{
NSLog(#"working");
[self.searchBar resignFirstResponder];
NSLog(#"working");
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:self.searchBar.text completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
MKCoordinateRegion region;
CLLocationCoordinate2D newLocation = [placemark.location coordinate];
region.center = [(CLCircularRegion *)placemark.region center];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:newLocation];
[annotation setTitle:self.searchBar.text];
[self.myMap addAnnotation:annotation];
MKMapRect mr = [self.myMap visibleMapRect];
MKMapPoint pt = MKMapPointForCoordinate([annotation coordinate]);
mr.origin.x = pt.x - mr.size.width * 0.5;
mr.origin.y = pt.y -mr.size.width * 0.25;
[self.myMap setVisibleMapRect:mr animated:YES];
}];
}
#end
Make sure you have
All delegate being set properly, this can be done either in code or
in storyboard.
Make use of correct delegate method to capture the
event.
If you think
- (void)searchBarBookmarkButtonClicked:(UISearchBar * )searchBar
then try using the other method which is more straight forward to trigger search
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Try this UISearchBar delegate method:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
Thank you #Rahul! Turns out I was using the wrong method!
.h:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController <UISearchBarDelegate,MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
#property (strong, nonatomic) IBOutlet MKMapView *myMap;
#end
.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.searchBar.delegate = self;
self.myMap.delegate = self;
}
- (void)searchBarBookmarkButtonClicked:(UISearchBar * )searchBar{
[self.searchBar resignFirstResponder];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:self.searchBar.text completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
MKCoordinateRegion region;
CLLocationCoordinate2D newLocation = [placemark.location coordinate];
region.center = [(CLCircularRegion *)placemark.region center];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:newLocation];
[annotation setTitle:self.searchBar.text];
[self.myMap addAnnotation:annotation];
MKMapRect mr = [self.myMap visibleMapRect];
MKMapPoint pt = MKMapPointForCoordinate([annotation coordinate]);
mr.origin.x = pt.x - mr.size.width * 0.5;
mr.origin.y = pt.y -mr.size.width * 0.25;
[self.myMap setVisibleMapRect:mr animated:YES];
}];
}
#end

MKMapView: Issue with changing pin image

I am trying to change the standard pin to my own image but I keep failing after several attempts.
I have tried different codes and guides that I have found here in this forum but none of them seems to work. I belive I am pasting the code in to my project wrongly. Any ideas how to replace the regular pin with my own image?
//.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MapPin : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
- (id)initWithLocation:(CLLocationCoordinate2D)coord;
#end
//.m
#import <Foundation/Foundation.h>
#import "MapPin.h"
#implementation MapPin
#synthesize coordinate,title,subtitle;
- (id)initWithLocation:(CLLocationCoordinate2D)coord{
self = [super init];
if (self) {
coordinate = coord;
}
return self;
}
#end
//Viewcontroller.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface FirstViewController : UIViewController <UIAlertViewDelegate, UIWebViewDelegate> {
MKMapView *mapview;
}
- (IBAction)information;
#property (strong, nonatomic) IBOutlet UIScrollView *ScrollView;
#property (strong, nonatomic) IBOutlet UIImageView *image;
#property (retain, nonatomic) IBOutlet MKMapView *mapview;
- (IBAction)showMenu;
- (IBAction)setMap:(id)sender;
- (IBAction)GetLocation:(id)sender;
#end
//Viewcontroller.m
#import "FirstViewController.h"
#import "MapPin.h"
#implementation FirstViewController
#synthesize ScrollView, image;
#synthesize mapview;
- (void)viewDidLoad{
MKCoordinateRegion region = { {0.0, 0.0}, {0.0,0.0}};
region.center.latitude = 55.709900;
region.center.longitude = 13.201207;
region.span.longitudeDelta = 0.032f;
region.span.latitudeDelta = 0.032f;
[mapview setRegion:region animated:YES];
MapPin *ann = [[MapPin alloc] init];
ann.title = #"test Town";
ann.subtitle = #"test Nation";
ann.coordinate = region.center;
ann.coordinate = region.center;
[mapview addAnnotation:ann];
MKCoordinateRegion region2 = { {0.0, 0.0}, {0.0,0.0}};
region2.center.latitude = 55.703904;
region2.center.longitude = 13.201207;
region2.span.longitudeDelta = 0.032f;
region2.span.latitudeDelta = 0.032f;
[mapview setRegion:region2 animated:YES];
MapPin *ann2 = [[MapPin alloc] init];
ann2.title = #"test Town";
ann2.subtitle = #"test Nation";
ann2.coordinate = region2.center;
ann2.coordinate = region2.center;
[mapview addAnnotation:ann2];
ScrollView.scrollEnabled = YES;
[ScrollView setContentSize:CGSizeMake(320, 515)];
}
-(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= MKPinAnnotationColorGreen;
pinView.enabled = YES;
pinView.canShowCallout = YES;
pinView.image=[UIImage imageNamed:#"test.png"]; //here I am giving the image
return pinView;
}
See my other answer for working implementation.
Setting an IBOutlet delegate:
Since you're using an IBOutlet for your MKMapView you should control-drag from your MKMapView in your storyboard/xib file to the ViewController/"File's Owner" and select "delegate" from the popup.
Here a SO answer that covers creating custom pins: Custom pins
Also,
pinView.image=[UIImage imageNamed:#"test.png"];
should be
pinView.image=[UIImage imageNamed:#"test"];
Reference: Image from imageNamed:
The following worked for me:
Make sure MapKit.framework has been added to your project.
Make sure test.png is in your project (preferably in Images.xcassets)
Control-drag from your mapView in your storyboard to the ViewController and connect "delegate".
Then...
#import "MapPin.h"
#import <MapKit/MapKit.h>
#interface ViewController () <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapview;
#end
#implementation ViewController
- (void)viewDidLoad
{
MKCoordinateRegion region = { {0.0, 0.0}, {0.0,0.0}};
region.center.latitude = 55.709900;
region.center.longitude = 13.201207;
region.span.longitudeDelta = 0.032f;
region.span.latitudeDelta = 0.032f;
[self.mapview setRegion:region animated:YES];
MapPin *ann = [[MapPin alloc] init];
ann.title = #"test Town";
ann.subtitle = #"test Nation";
ann.coordinate = region.center;
ann.coordinate = region.center;
[self.mapview addAnnotation:ann];
MKCoordinateRegion region2 = { {0.0, 0.0}, {0.0,0.0}};
region2.center.latitude = 55.703904;
region2.center.longitude = 13.201207;
region2.span.longitudeDelta = 0.032f;
region2.span.latitudeDelta = 0.032f;
[self.mapview setRegion:region2 animated:YES];
MapPin *ann2 = [[MapPin alloc] init];
ann2.title = #"test Town";
ann2.subtitle = #"test Nation";
ann2.coordinate = region2.center;
ann2.coordinate = region2.center;
[self.mapview addAnnotation:ann2];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if(annotationView) {
return annotationView;
} else {
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationIdentifier];
annotationView.image = [UIImage imageNamed:#"test"];
return annotationView;
}
}
#end
So I have followed the guidelines above, added the line of code and step3. Control-drag from your mapView in your storyboard to the ViewController and connect "delegate". which I named "pin".
But my image wont appear...I'll paste the new code again..there must be something wrong in it.
//Viewcontroller.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface FirstViewController : UIViewController <UIAlertViewDelegate, UIWebViewDelegate, MKMapViewDelegate> {
MKMapView *mapview;
}
- (IBAction)information;
#property (strong, nonatomic) IBOutlet UIScrollView *ScrollView;
#property (strong, nonatomic) IBOutlet UIImageView *image;
#property (retain, nonatomic) IBOutlet MKMapView *mapview;
#property (strong, nonatomic) IBOutlet MKMapView *pin;
- (IBAction)showMenu;
- (IBAction)setMap:(id)sender;
- (IBAction)GetLocation:(id)sender;
#end
//Viewcontroller.m
#import "FirstViewController.h"
#import "MapPin.h"
#implementation FirstViewController
#synthesize ScrollView, image;
#synthesize mapview;
#synthesize pin;
- (void)viewDidLoad{
MKCoordinateRegion region = { {0.0, 0.0}, {0.0,0.0}};
region.center.latitude = 55.709900;
region.center.longitude = 13.201207;
region.span.longitudeDelta = 0.032f;
region.span.latitudeDelta = 0.032f;
[self.mapview setRegion:region animated:YES];
MapPin *ann = [[MapPin alloc] init];
ann.title = #"test Town";
ann.subtitle = #"test Nation";
ann.coordinate = region.center;
ann.coordinate = region.center;
[self.mapview addAnnotation:ann];
MKCoordinateRegion region2 = { {0.0, 0.0}, {0.0,0.0}};
region2.center.latitude = 55.703904;
region2.center.longitude = 13.201207;
region2.span.longitudeDelta = 0.032f;
region2.span.latitudeDelta = 0.032f;
[self.mapview setRegion:region2 animated:YES];
MapPin *ann2 = [[MapPin alloc] init];
ann2.title = #"test Town";
ann2.subtitle = #"test Nation";
ann2.coordinate = region2.center;
ann2.coordinate = region2.center;
[self.mapview addAnnotation:ann2];
ScrollView.scrollEnabled = YES;
[ScrollView setContentSize:CGSizeMake(320, 515)];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if(annotationView) {
return annotationView;
} else {
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationIdentifier];
annotationView.image = [UIImage imageNamed:#"test"];
return annotationView;
}
}
#end

Using MKOverlayRenderer in iOS7 to display UIImage

I am trying to display a UIImage as a overlay for a map-based iPad application. I attempted to follow the 4 steps to setting a custom overlay defined in Apple's documentation: define the overlay data object, define the object renderer, implement the map view in map view delegate, and add overlay data object to to map view. After attempting to do all these, there is no overlay when I run the simulator. Any advice would be fantastic. My code is as follows
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "bjorkOverlay.h"
#import "bjorkOverlayRenderer.h"
#interface TUTViewController : UIViewController <MKMapViewDelegate>
{
CLLocationManager *locationManager;
CLLocation *location;
}
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#property(nonatomic) MKCoordinateRegion region;
#property (nonatomic, readonly) MKMapRect boundingMapRect;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, readonly) CLLocationCoordinate2D bjorkOverlayCenterPoint;
#property (nonatomic, readonly) MKMapRect bjorkOverlayBoundingMapRect;
#end
ViewController.m
#import "TUTViewController.h"
#import "bjorkOverlay.h"
#import "bjorkOverlayRenderer.h"
#import MapKit;
#interface TUTViewController () <MKMapViewDelegate>
#end
#implementation TUTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
_mapView.showsUserLocation = YES;
_mapView.delegate = self;
CLLocationCoordinate2D lowerLeftCoord = CLLocationCoordinate2DMake( 45.022943 ,-87.146606);
MKMapPoint lowerLeft = MKMapPointForCoordinate(lowerLeftCoord);
CLLocationCoordinate2D upperRightCoord = CLLocationCoordinate2DMake( 45.048513, -87.124765);
MKMapPoint upperRight = MKMapPointForCoordinate(upperRightCoord);
MKMapRect mapRect = MKMapRectMake(lowerLeft.x, upperRight.y, upperRight.x - lowerLeft.x, lowerLeft.y - upperRight.y);
[self.mapView setVisibleMapRect:mapRect animated:YES];
bjorkOverlay * mapOverlay = [[bjorkOverlay alloc] init];
[_mapView addOverlay:mapOverlay];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay: (id<MKOverlay>)overlay {
MKOverlayRenderer *mapOverlay = [[MKOverlayRenderer alloc] init];
return mapOverlay;
}
// Do any additional setup after loading the view, typically from a nib.
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
bjorkOverlay.h
#import <Foundation/Foundation.h>
#import MapKit;
#interface bjorkOverlay : NSObject <MKOverlay>
+ (id)overlayWithCoordinate:(CLLocationCoordinate2D)coordinate;
#property (nonatomic, assign) CLLocationCoordinate2D bjorkOverlayCenterPoint;
#property (nonatomic) MKMapRect bjorkOverlayBoundingMapRect;
#end
bjorkOverlay.m
#import "bjorkOverlay.h"
#import MapKit;
#implementation bjorkOverlay
+ (id)overlayWithCoordinate:(CLLocationCoordinate2D)coordinate radius:(CLLocationDistance)radius{
bjorkOverlay* overlay = [[bjorkOverlay alloc] init];
overlay.coordinate = coordinate;
return overlay;
}
-(MKMapRect)boundingMapRect{
CLLocationCoordinate2D lowerLeftCoord = CLLocationCoordinate2DMake( 45.022943 ,-87.146606);
MKMapPoint lowerLeft = MKMapPointForCoordinate(lowerLeftCoord);
CLLocationCoordinate2D upperRightCoord = CLLocationCoordinate2DMake( 45.048513, -87.124765);
MKMapPoint upperRight = MKMapPointForCoordinate(upperRightCoord);
MKMapRect mapRect = MKMapRectMake(lowerLeft.x, upperRight.y, upperRight.x - lowerLeft.x, lowerLeft.y - upperRight.y);
return mapRect;
}
- (CLLocationCoordinate2D)bjorkOverlayCenterPoint
{
CLLocationCoordinate2D coord1 = {
45.035728,-87.1356855
};
return coord1;
}
#end
bjorkOverlayRenderer.h
#import <MapKit/MapKit.h>
#interface bjorkOverlayRenderer : MKOverlayRenderer
#end
bjorkOverlayRender.m
#import "bjorkOverlayRenderer.h"
#implementation bjorkOverlayRenderer
- (void)drawMapRect:(MKMapRect)mapRect
zoomScale:(MKZoomScale)zoomScale
inContext:(CGContextRef)ctx
{
UIImage *image = [UIImage imageNamed:#"overlay.png"];
CGImageRef imageReference = image.CGImage;
MKMapRect theMapRect = [self.overlay boundingMapRect];
CGRect theRect = [self rectForMapRect:theMapRect];
CGRect clipRect = [self rectForMapRect:mapRect];
CGContextAddRect(ctx, clipRect);
CGContextClip(ctx);
CGContextDrawImage(ctx, theRect, imageReference);
}
#end
Any advice would be great or if you have seen sample code for MKOverlayRenderer I would appreciate a link. Thanks

Add a marker to my map

I'm new to iOS, and it's so different from Android logic that I can't find how to add a marker to a map :-|
I've added a MKMapView to my xib
I've added this code to my .m (trimmed)
#import "AppDelegate.h"
#import <MapKit/MapKit.h>
#interface Dove ()
#property (weak,nonatomic) IBOutlet MKMapView *mappa;
#end
#define METERS_PER_MILE 1609.344
#implementation Dove
- (IBAction)vaiHome:(id)sender {
Index *second = [[Index alloc] initWithNibName:#"Index" bundle:nil];
[self presentViewController:second animated:YES completion:nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 45.40170;
zoomLocation.longitude= 8.91552;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, METERS_PER_MILE, METERS_PER_MILE);
[_mappa setRegion:viewRegion animated:YES];
[_mappa regionThatFits:viewRegion];
}
Now, how can I display a pin at that position? It should simple, but I can't find a solution :-|
Also, the map remain in united states but it most go to the marker.
Thanks a lot.
First you have to setup the annotation marker (call this in your viewdidload):
- (void)setupAnnotation
{
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 45.40170;
zoomLocation.longitude= 8.91552;
NARMapViewAnnotation* annot = [[NARMapViewAnnotation alloc] initWithCoord:zoomLocation];
[_mapView addAnnotation:annot];
}
Then you have to setup the MKMapViewDelegate method:
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView* annotView = [views objectAtIndex:0];
id<MKAnnotation> mp = [annotView annotation];
MKCoordinateRegion region = [mv regionThatFits:MKCoordinateRegionMakeWithDistance([mp coordinate], REGION_WINDOW, REGION_WINDOW)];
[mv setRegion:region animated:YES];
}
NARMapViewAnnotation:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface NARMapViewAnnotation : NSObject <MKAnnotation>
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
- (id)initWithCoord:(CLLocationCoordinate2D)coord;
#end
#import "NARMapViewAnnotation.h"
#implementation NARMapViewAnnotation
- (id)initWithCoord:(CLLocationCoordinate2D)coord
{
if (self = [super init])
{
_coordinate = coord;
}
return self;
}
#end

Using AVSpeechSynthesizer to read a description of location on a Map

My map has 4 or 5 points close to each other and right now using AVSpeechSynthesizer I've got it so that it will say the name of the location (which is also displayed in a little bubble).
I want it to still show that bubble but when clicked I want it to say a description of that place that I would have specified. This is my code at the moment:
MapViewAnnotation.h
#interface MapViewAnnotation : NSObject <MKAnnotation> {
NSString *title;
CLLocationCoordinate2D coordinate;
NSString *desc;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, readonly) NSString *desc;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d initWithDesc:(NSString *)dsc;
MapViewAnnotation.m
#implementation MapViewAnnotation
#synthesize title, coordinate, desc;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d initWithDesc:(NSString *)dsc {
[super init];
title = ttl;
coordinate = c2d;
desc = dsc;
return self;
MapViewController.h
#interface MapViewController : UIViewController {
MKMapView *mapView;
}
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) AVSpeechSynthesizer *synthesizer;
MapViewController.m
- (void)viewDidLoad
{
// Set some coordinates for our position : Cutty Sark
CLLocationCoordinate2D location;
location.latitude = (double) 51.482997;
location.longitude = (double) -0.010072;
// Royal Observatory
CLLocationCoordinate2D twoLocation;
twoLocation.latitude = (double) 51.477805;
twoLocation.longitude = (double) -0.001430;
//Royal Naval College
CLLocationCoordinate2D threeLocation;
threeLocation.latitude = (double) 51.483344;
threeLocation.longitude = (double) -0.006799;
//Queen's House
CLLocationCoordinate2D fourLocation;
fourLocation.latitude = (double) 51.481383;
fourLocation.longitude = (double) -0.003722;
//National Maritime Museum
CLLocationCoordinate2D fiveLocation;
fiveLocation.latitude = (double) 51.481050;
fiveLocation.longitude = (double) -0.005578;
// Add Cutty Sark annotation to MapView
MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"Cutty Sark" andCoordinate:location initWithDesc:#"Description about Cutty Sark"];
[self.mapView addAnnotation:newAnnotation];
self.mapView.delegate = self;
[newAnnotation release];
// Add Royal Observatory annotation to MapView
newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"Royal Observatory" andCoordinate:twoLocation initWithDesc:#"Description about Cutty Sark"];
[self.mapView addAnnotation:newAnnotation];
[newAnnotation release];
// Add Royal Naval College annotation to MapView
newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"Royal Naval College" andCoordinate:threeLocation initWithDesc:#"Description about Cutty Sark"];
[self.mapView addAnnotation:newAnnotation];
[newAnnotation release];
// Add Queen's House annotation to MapView
newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"Queen's House" andCoordinate:fourLocation initWithDesc:#"Description about Cutty Sark"];
[self.mapView addAnnotation:newAnnotation];
[newAnnotation release];
// Add National Maritime Museum annotation to MapView
newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"National Maritime Museum" andCoordinate:fiveLocation initWithDesc:#"Description about Cutty Sark"];
[self.mapView addAnnotation:newAnnotation];
[newAnnotation release];
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)anView
{
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc]init];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:((MapViewAnnotation *)anView).desc];
[utterance setRate:0.5];
[synthesizer speakUtterance:utterance];
}
// When a map annotation point is added, zoom to it (1500 range)
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *annotationView = [views objectAtIndex:0];
id <MKAnnotation> mp = [annotationView annotation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 1500, 1500);
[mv setRegion:region animated:YES];
//[mv selectAnnotation:mp animated:YES];
}
Any help would be appreciated!
EDIT
Here is the NSLog:
In the didSelectAnnotationView delegate method, the anView parameter is the MKAnnotationView.
That is, anView is the view (MKAnnotationView or MKPinAnnotationView class) object of the annotation.
It is not the model (your MapViewAnnotation class) object of the annotation.
To refer to the annotation model instance that the view is for, use the view's annotation property and cast it to your class:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)anView
{
//Get a reference to the annotation this view is for...
id<MKAnnotation> annSelected = anView.annotation;
//Before casting, make sure this annotation is our custom type
//(and not some other type like MKUserLocation)...
if ([annSelected isKindOfClass:[MapViewAnnotation class]])
{
MapViewAnnotation *mva = (MapViewAnnotation *)annSelected;
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc]init];
AVSpeechUtterance *utterance =
[AVSpeechUtterance speechUtteranceWithString:mva.desc];
[utterance setRate:0.5];
[synthesizer speakUtterance:utterance];
}
}

Resources