how to detect click on annotation mapkit and run action - objective-c

I create one app that have mapkit and I can to add specific annotations in my map and I want when to tap (click) on any annotation do one method or one action but I don't about it.
please guide me . I searching many time in google but don't give correct answer for my question.
this is my code :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
locationManager = [[CLLocationManager alloc] init];
[self GetMyLocation];
mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, 320, 500)];
mapView.mapType = MKMapTypeStandard;
mapView.zoomEnabled = YES;
mapView.scrollEnabled = YES;
mapView.showsUserLocation = YES;
[mapView.userLocation setTitle:#"I'm Here"];
[mapView.userLocation setSubtitle:#"Rahnova Corpration"];
[self.view addSubview:mapView];
[self addAnnonations];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGesture:)];
[self.mapView addGestureRecognizer:longPressGesture];
}
- (void) addAnnonations{
NSArray *title = [[NSArray alloc]initWithObjects:#"Rome",#"Chelsea", nil];
NSArray *subtitle = [[NSArray alloc]initWithObjects:#"Red",#"Blue", nil];
NSArray *latitude = [[NSArray alloc]initWithObjects:#"35.738000",#"35.739901", nil];
NSArray *longitude = [[NSArray alloc]initWithObjects:#"51.310029",#"51.312018", nil];
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc]init];
[dictionary setObject:title forKey:#"title"];
[dictionary setObject:subtitle forKey:#"subtitle"];
[dictionary setObject:latitude forKey:#"latitude"];
[dictionary setObject:longitude forKey:#"longitude"];
for (int i = 0; i <= 1; i++) {
NSString *Name = [[dictionary objectForKey:#"title"]objectAtIndex:i];
NSString *SubName = [[dictionary objectForKey:#"subtitle"]objectAtIndex:i];
double Lati = [[[dictionary objectForKey:#"latitude"]objectAtIndex:i] doubleValue];
double Long = [[[dictionary objectForKey:#"longitude"]objectAtIndex:i] doubleValue];
[self SetTitle:Name SetSubtitle:SubName SetLatitude:Lati SetLongitude:Long];
}
}
- (void) SetTitle:(NSString *)title SetSubtitle:(NSString *)subtitle SetLatitude:(double)latitude SetLongitude:(double)longitude{
//create coordinate for use annotation
CLLocationCoordinate2D annoLocation;
annoLocation.latitude = latitude;
annoLocation.longitude = longitude;
Annotation *myAnnonation = [[Annotation alloc]init];
myAnnonation.coordinate = annoLocation;
myAnnonation.title = title;
myAnnonation.subtitle = subtitle;
[self.mapView addAnnotation:myAnnonation];
}
- (void) centerLocation{
//create region
MKCoordinateRegion myRegion;
CLLocationCoordinate2D center;
center.latitude = latitudes;
center.longitude = longitudes;
//span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span = span;
[mapView setRegion:myRegion animated:YES];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
longitudes = currentLocation.coordinate.longitude;
latitudes = currentLocation.coordinate.latitude;
[self centerLocation];
}
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}

dude try this :
Xcode 4 iPhone SDK Tutorial - How to add different actions to each annotation-pin HD
or this :
Detecting when MKAnnotation is selected in MKMapView

Related

Objective C - Have only one pin at a time?

I have 2 different set of pins on top of a map view. One pin appears first and it's the user location, then when you search for a location in the search bar multiple pins appear depending on the location. I want to have one pin showing at a time. Once you search for the location the user's location pin should disappear, and once you select one of the multiple pins you searched the others should disappear.
Here's my code:
#import "UbicacionVC.h"
#import "SWRevealViewController.h"
#import <MapKit/Mapkit.h>
#import "Location.h"
#interface UbicacionVC ()
#end
#implementation UbicacionVC
#synthesize mapView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self inicializarComponentes];
self.mapView.delegate = self;
self.searchBar.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)inicializarComponentes {
[self.btnContinuar.layer setCornerRadius:20.0f];
[self.btnCancelar.layer setCornerRadius:20.0f];
////
UITapGestureRecognizer *gestureMenu = [[UITapGestureRecognizer alloc] init];
[gestureMenu addTarget:self.revealViewController action:#selector(revealToggle:)];
[gestureMenu setCancelsTouchesInView:NO];
[self.btnLeftMenu addGestureRecognizer:gestureMenu];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
////
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[self->locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
CLLocationDegrees lat = newLocation.coordinate.latitude;
CLLocationDegrees lon = newLocation.coordinate.longitude;
CLLocation * location = [[CLLocation alloc]initWithLatitude:lat longitude:lon];
self.viewRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 500, 500);
[self.mapView setRegion:self.viewRegion];
}
-(void)localSearch:(NSString*)searchString{
[self.mapView setRegion:self.viewRegion];
MKLocalSearchRequest * request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = [searchString lowercaseString];
request.region = self.viewRegion;
MKLocalSearch* search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
if([response.mapItems count] == 0){
NSLog(#"No matches \n");
}
else{
for(MKMapItem * item in response.mapItems){
Location * pin = [[Location alloc] initWith:item.placemark.title andSubtitle:item.phoneNumber andCoordinate:item.placemark.coordinate andImageName:#"" andURL:item.url.absoluteString];
[self.mapView addAnnotation:pin];
}
}
}];
}
#pragma mark UISearchBarDelegate
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
[searchBar resignFirstResponder];
[self.mapView removeAnnotations:[self.mapView annotations]];
[self localSearch:searchBar.text];
}
#pragma mark MKMapViewDelegate
-(MKAnnotationView*)mapView:(MKMapView*)sender viewForAnnotation: (id<MKAnnotation>)annotation{
static NSString* identifier = #"reusablePin";
MKAnnotationView * aView = [sender dequeueReusableAnnotationViewWithIdentifier:identifier];
if(!aView){
aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
aView.canShowCallout = YES;
}
aView.annotation = annotation;
return aView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"%#",view.annotation.title);
NSLog(#"%#",view.annotation.subtitle);
}
I want to have one pin showing at a time.
How about break; in for loop?
for(MKMapItem * item in response.mapItems){
Location * pin = [[Location alloc] initWith:item.placemark.title andSubtitle:item.phoneNumber andCoordinate:item.placemark.coordinate andImageName:#"" andURL:item.url.absoluteString];
[self.mapView addAnnotation:pin];
// one pin showed
break;
}
Once you search for the location the user's location pin should disappear,
and once you select one of the multiple pins you searched the others should disappear.
You can use didSelectAnnotationView method.
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
// once you select one of the multiple pins, the others should disappear.
for (MKPointAnnotation *annotation in mapView.annotations) {
if (view.annotation != annotation) {
[mapView removeAnnotation:annotation];
NSLog(#"yes!!");
}
}
}

Showing distance from user location to other mapview annotations, but the calculated distance says 0.0000? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm attempting to display the distance from a user's current location to other mapview annotations (Pulled from my MapViewController) in a label (located on a TableViewController), but for some reason the calculated distance label says 0.0000 when I run it through the simulator? Even after I've customized my "current location". Any ideas as to why?
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (nonatomic, strong) IBOutlet MKMapView *mapView;
#property (nonatomic, retain) NSMutableArray *dispensaries;
#property (nonatomic, retain) NSMutableData *data;
#end
MapViewController.m
[super viewDidUnload];
NSLog(#"Getting Device Locations");
NSString *hostStr = #"http://stylerepublicmagazine.com/dispensaries.php";
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:hostStr]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
NSLog(#"server output: %#", serverOutput);
NSMutableArray *array = [[[serverOutput objectFromJSONString] mutableCopy] autorelease];
dispensaries = [serverOutput objectFromJSONString];
NSLog(#"%#", [serverOutput objectFromJSONString]);
for (NSDictionary *dictionary in array) {
assert([dictionary respondsToSelector:#selector(objectForKey:)]);
CLLocationCoordinate2D coord = {[[dictionary objectForKey:#"lat"] doubleValue], [[dictionary objectForKey:#"lng"] doubleValue]};
MapViewAnnotation *ann = [[MapViewAnnotation alloc] init];
ann.title = [dictionary objectForKey:#"Name"];
ann.subtitle = [dictionary objectForKey:#"Address1"];
ann.coordinate = coord;
[mapView addAnnotation:ann];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
self.mapView.delegate = self;
}
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 2000, 2000);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"You Are Here";
point.subtitle = #"Your current location";
[self.mapView addAnnotation:point];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
for (MapViewAnnotation *annotation in self.mapView.annotations) {
CLLocationCoordinate2D coord = [annotation coordinate];
CLLocation *userLocation = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
annotation.distance = [newLocation distanceFromLocation:userLocation];
CLLocationDistance calculatedDistance = [userLocation distanceFromLocation:userLocation];
annotation.distance = calculatedDistance;
}
NSArray *sortedArray;
sortedArray = [self.mapView.annotations sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSNumber *first = [NSNumber numberWithDouble:[(MapViewAnnotation*)a distance]];
NSNumber *second = [NSNumber numberWithDouble:[(MapViewAnnotation*)b distance]];
return [first compare:second];
}];
}
TableViewController.h
#import <UIKit/UIKit.h>
#import "MapViewController.h"
#interface TableViewController : UITableViewController {
IBOutlet UITableView *DispensaryTableView;
NSArray *dispensaries;
NSMutableData *data;
}
#property CLLocationDistance calculatedDistance;
#end
TableViewController.m
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://stylerepublicmagazine.com/dispensaries.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
dispensaries = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
[DispensaryTableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"The download could not complete - please make sure that you're connected to 3G or Wi-Fi." delegate:nil
cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dispensaries count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DispensaryTableIdentifier = #"DispensaryCell";
DispensaryCell *cell = (DispensaryCell *)[tableView dequeueReusableCellWithIdentifier:DispensaryTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DispensaryCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.nameLabel.text = [[dispensaries objectAtIndex:indexPath.row] objectForKey:#"Name"];
cell.distanceLabel.text = [NSString stringWithFormat:#"%f", calculatedDistance];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
It seems that this line:
CLLocationDistance calculatedDistance = [userLocation distanceFromLocation:userLocation];
Computes distance to itself?
The line before it seems to calculate the annotation distance correctly, but the you overwrite it in the line after...

Geofencing in Xcode 4, didEnterRegion gives multiple callbacks

I'm trying to create an app in Xcode 4 based on geofencing. The app will notify the user when entering a region with certain center coordinates and a certain radius given in meters. All my regions are saved in a p-list. However I get multiple callbacks and more locations than I want gets called (i.e. locations not even in the right location gets called. Below you can see our code. I have also added a kml-layer which you can ignore because it has nothing to do with the fencing. My p-list is an array and contains of 20 items with the type dictionary and the keys are title, latitude, longitude and radius. The radius is set to 50 meters.
ViewController.h
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#implementation ViewController
#synthesize coordinateLabel;
#synthesize mapView;
CLLocationManager *_locationManager;
NSArray *_regionArray;
- (void)viewDidLoad
{
[super viewDidLoad];
[self initializeMap];
[self initializeLocationManager];
NSArray *geofences = [self buildGeofenceData];
[self initializeRegionMonitoring:geofences];
[self initializeLocationUpdates];
}
- (void)viewDidUnload
{
[self setCoordinateLabel:nil];
[self setMapView:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)initializeMap {
CLLocationCoordinate2D initialCoordinate;
initialCoordinate.latitude = 41.88072;
initialCoordinate.longitude = -87.67429;
[self.mapView setRegion:MKCoordinateRegionMakeWithDistance(initialCoordinate, 400, 400) animated:YES];
self.mapView.centerCoordinate = initialCoordinate;
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
- (void)initializeLocationManager {
// Check to ensure location services are enabled
if(![CLLocationManager locationServicesEnabled]) {
[self showAlertWithMessage:#"You need to enable location services to use this app."];
return;
}
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
}
- (void) initializeRegionMonitoring:(NSArray*)geofences {
if (_locationManager == nil) {
[NSException raise:#"Location Manager Not Initialized" format:#"You must initialize location manager first."];
}
if(![CLLocationManager regionMonitoringAvailable]) {
[self showAlertWithMessage:#"This app requires region monitoring features which are unavailable on this device."];
return;
}
for(CLRegion *geofence in geofences) {
[_locationManager startMonitoringForRegion:geofence];
}
}
- (NSArray*) buildGeofenceData {
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"regions" ofType:#"plist"];
_regionArray = [NSArray arrayWithContentsOfFile:plistPath];
NSMutableArray *geofences = [NSMutableArray array];
for(NSDictionary *regionDict in _regionArray) {
CLRegion *region = [self mapDictionaryToRegion:regionDict];
[geofences addObject:region];
}
return [NSArray arrayWithArray:geofences];
}
- (CLRegion*)mapDictionaryToRegion:(NSDictionary*)dictionary {
NSString *title = [dictionary valueForKey:#"title"];
CLLocationDegrees latitude = [[dictionary valueForKey:#"latitude"] doubleValue];
CLLocationDegrees longitude =[[dictionary valueForKey:#"longitude"] doubleValue];
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
CLLocationDistance regionRadius = [[dictionary valueForKey:#"radius"] doubleValue];
return [[CLRegion alloc] initCircularRegionWithCenter:centerCoordinate
radius:regionRadius
identifier:title];
}
- (void)initializeLocationUpdates {
[_locationManager startUpdatingLocation];
}
#pragma mark - Location Manager - Region Task Methods
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Entered Region - %#", region.identifier);
[self showRegionAlert:#"Entering Region" forRegion:region.identifier];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"Exited Region - %#", region.identifier);
[self showRegionAlert:#"Exiting Region" forRegion:region.identifier];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"Started monitoring %# region", region.identifier);
}
#pragma mark - Location Manager - Standard Task Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
self.coordinateLabel.text = [NSString stringWithFormat:#"%f,%f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
}
#pragma mark - Alert Methods
- (void) showRegionAlert:(NSString *)alertText forRegion:(NSString *)regionIdentifier {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:alertText
message:regionIdentifier
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
- (void)showAlertWithMessage:(NSString*)alertText {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Location Services Error"
message:alertText
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
#end
ViewController.m
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#implementation ViewController
#synthesize coordinateLabel;
#synthesize mapView;
#synthesize kmlParser;
CLLocationManager *_locationManager;
NSArray *_regionArray;
- (void)viewDidLoad
{
[super viewDidLoad];
[self initializeMap];
[self initializeLocationManager];
NSArray *geofences = [self buildGeofenceData];
[self initializeRegionMonitoring:geofences];
[self initializeLocationUpdates];
// Locate the path to the route.kml file in the application's bundle
// and parse it with the KMLParser.
NSString *path = [[NSBundle mainBundle] pathForResource:#"urbanPOIsthlm" ofType:#"kml"];
NSURL *url = [NSURL fileURLWithPath:path];
kmlParser = [[KMLParser alloc] initWithURL:url];
[kmlParser parseKML];
// Add all of the MKOverlay objects parsed from the KML file to the map.
NSArray *overlays = [kmlParser overlays];
[mapView addOverlays:overlays];
// Add all of the MKAnnotation objects parsed from the KML file to the map.
NSArray *annotations = [kmlParser points];
[mapView addAnnotations:annotations];
// Walk the list of overlays and annotations and create a MKMapRect that
// bounds all of them and store it into flyTo.
MKMapRect flyTo = MKMapRectNull;
for (id <MKOverlay> overlay in overlays) {
if (MKMapRectIsNull(flyTo)) {
flyTo = [overlay boundingMapRect];
} else {
flyTo = MKMapRectUnion(flyTo, [overlay boundingMapRect]);
}
}
for (id <MKAnnotation> annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(flyTo)) {
flyTo = pointRect;
} else {
flyTo = MKMapRectUnion(flyTo, pointRect);
}
}
// Position the map so that all overlays and annotations are visible on screen.
mapView.visibleMapRect = flyTo;
}
- (void)viewDidUnload
{
[self setCoordinateLabel:nil];
[self setMapView:nil];
//DERAS alltså KML!!!
[kmlParser release];
///
[super viewDidUnload];
}
/////Deras alltså KML!!!
#pragma mark MKMapViewDelegate
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
return [kmlParser viewForOverlay:overlay];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
return [kmlParser viewForAnnotation:annotation];
}
//////////
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)initializeMap {
CLLocationCoordinate2D initialCoordinate;
initialCoordinate.latitude = 59.3353733;
initialCoordinate.longitude = 18.0712647;
[self.mapView setRegion:MKCoordinateRegionMakeWithDistance(initialCoordinate, 400, 400) animated:YES];
self.mapView.centerCoordinate = initialCoordinate;
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
- (void)initializeLocationManager {
// Check to ensure location services are enabled
if(![CLLocationManager locationServicesEnabled]) {
[self showAlertWithMessage:#"You need to enable location services to use this app."];
return;
}
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
}
- (void) initializeRegionMonitoring:(NSArray*)geofences {
if (_locationManager == nil) {
[NSException raise:#"Location Manager Not Initialized" format:#"You must initialize location manager first."];
}
if(![CLLocationManager regionMonitoringAvailable]) {
[self showAlertWithMessage:#"This app requires region monitoring features which are unavailable on this device."];
return;
}
for(CLRegion *geofence in geofences) {
[_locationManager startMonitoringForRegion:geofence
desiredAccuracy:kCLLocationAccuracyBest];
}
}
- (NSArray*) buildGeofenceData {
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"regions" ofType:#"plist"];
_regionArray = [NSArray arrayWithContentsOfFile:plistPath];
NSMutableArray *geofences = [NSMutableArray array];
for(NSDictionary *regionDict in _regionArray) {
CLRegion *region = [self mapDictionaryToRegion:regionDict];
[geofences addObject:region];
}
return [NSArray arrayWithArray:geofences];
}
- (CLRegion*)mapDictionaryToRegion:(NSDictionary*)dictionary {
NSString *title = [dictionary valueForKey:#"title"];
CLLocationDegrees latitude = [[dictionary valueForKey:#"latitude"] doubleValue];
CLLocationDegrees longitude =[[dictionary valueForKey:#"longitude"] doubleValue];
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
//CLLocationDistance regionRadius = 50.000;
CLLocationDistance regionRadius = [[dictionary valueForKey:#"radius"] doubleValue]; //<--STOD DOUBLE ISTÄLLET
return [[CLRegion alloc] initCircularRegionWithCenter:centerCoordinate
radius:regionRadius
identifier:title];
}
- (void)initializeLocationUpdates {
[_locationManager startUpdatingLocation];
}
#pragma mark - Location Manager - Region Task Methods
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(#"Entered Region - %#", region.identifier);
[self showRegionAlert:#"Entering Region" forRegion:region.identifier];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"Exited Region - %#", region.identifier);
[self showRegionAlert:#"Exiting Region" forRegion:region.identifier];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"Started monitoring %# region", region.identifier);
}
#pragma mark - Location Manager - Standard Task Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
self.coordinateLabel.text = [NSString stringWithFormat:#"%f,%f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
}
#pragma mark - Alert Methods
- (void) showRegionAlert:(NSString *)alertText forRegion:(NSString *)regionIdentifier {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:alertText
message:regionIdentifier
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
- (void)showAlertWithMessage:(NSString*)alertText {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Location Services Error"
message:alertText
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
#end
Appdelegate.h
#import <UIKit/UIKit.h>
#class ViewController;
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet ViewController *viewController;
#end
Appdelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
#implementation AppDelegate
//DERAS ALLTSÅ KML!!
#synthesize window;
#synthesize viewController;
//
//Deras alltså KML!!
#pragma mark -
#pragma mark Application lifecycle
//
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
//Deras alltså KML!!
[window addSubview:viewController.view];
//
return YES;
}
//Deras alltså KML!!!
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
//
#end

Add a image to MKPointAnnotation

Is it possible?
Im performing an action here that gives to me a pin. But i need a image. And MKAnnotation seems complicated for me.
- (void)abreMapa:(NSString *)endereco {
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",
[endereco stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = 0.0;
double longitude = 0.0;
if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else {
//Show error
}
CLLocationCoordinate2D coordinate;
coordinate.latitude = latitude;
coordinate.longitude = longitude;
myMap.region = MKCoordinateRegionMakeWithDistance(coordinate, 2000, 2000);
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:coordinate];
[annotation setTitle:#"Some Title"];
[myMap addAnnotation:annotation];
// Coloca o icone
[self.view addSubview:mapa];
}
Thanks!
You'll need to set up an MKMapViewDelegate, and implement
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
Here's sample code, stolen from the MapCallouts sample code provided on Apple's developer site. I've modified it to focus on the important details. You can see below that the key is to set the image on an annotation view, and return that annotation view from this method.
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *SFAnnotationIdentifier = #"SFAnnotationIdentifier";
MKPinAnnotationView *pinView =
(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:SFAnnotationIdentifier];
if (!pinView)
{
MKAnnotationView *annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:SFAnnotationIdentifier] autorelease];
UIImage *flagImage = [UIImage imageNamed:#"flag.png"];
// You may need to resize the image here.
annotationView.image = flagImage;
return annotationView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
We use dequeueReusableAnnotationViewWithIdentifier to grab an already created view to make reuse of our annotation views. If one isn't returned we create a new one. This prevents us from creating hundreds of MKAnnotationViews if only a few are ever in sight at the same time.

wait for CLLocationManager to finish before tweeting

I want to wait for latitude.text and longtitude.text to be filled in before sending a tweet, this code works fine, but I would rather not put the tweeting part in locationManager because I also want to sometimes update the current location without sending a tweet. How can I make sure the txt gets filled in before sending the tweet without doing this?
- (IBAction)update {
latitude.text =#"";
longitude.text =#"";
locmanager = [[CLLocationManager alloc] init];
[locmanager setDelegate:self];
[locmanager setDesiredAccuracy:kCLLocationAccuracyBest];
[locmanager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D location = [newLocation coordinate];
latitude.text = [NSString stringWithFormat: #"%f", location.latitude];
longitude.text = [NSString stringWithFormat: #"%f", location.longitude];
TwitterRequest * t = [[TwitterRequest alloc] init];
t.username = #"****";
t.password = #"****";
[twitterMessageText resignFirstResponder];
loadingActionSheet = [[UIActionSheet alloc] initWithTitle:#"Posting To Twitter..." delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[loadingActionSheet showInView:self.view];
[t statuses_update:twitterMessageText.text andLat:latitude.text andLong:longitude.text delegate:self requestSelector:#selector(status_updateCallback:)];
twitterMessageText.text=#"";
}
You could register listeners in your class that implements the CLLocationManagerDelegate. For example,
#interface GPS : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
NSMutableArray *listeners;
}
- (void) addListener:(id<GPSListener>)listener;
#end
#implementation GPS
- (IBAction)update {
latitude.text =#"";
longitude.text =#"";
locmanager = [[CLLocationManager alloc] init];
[locmanager setDelegate:self];
[locmanager setDesiredAccuracy:kCLLocationAccuracyBest];
[locmanager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CLLocationCoordinate2D location = [newLocation coordinate];
latitude.text = [NSString stringWithFormat: #"%f", location.latitude];
longitude.text = [NSString stringWithFormat: #"%f", location.longitude];
// Inform the listeners.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for ( id<GPSListener> listener in listeners )
{
#try
{
[listener onLocationChangeForLatitude:latitude.text longitude:longitude];
}
#catch (NSException *e)
{
NSLog(#"Unhandled exception in onLocationChange");
}
}
[pool release];
}
- (void) addListener:(id<GPSListener>)listener
{
[listeners addObject:listener];
}
#end
The you can have a set of listeners that register themselves with your GPS object.
#protocol GPSListener {
- (void) onLocationChangeForLatitude:(NSString *)latitude longitude:(NSString *)longitude;
}
So now you can have a TweetGPSListener
#interface TweetGPSListener : NSObject <GPSListener> {
}
#end
#implementation TweetGPSListener
- (void) onLocationChangeForLatitude:(NSString *)latitude longitude:(NSString *)longitude {
TwitterRequest * t = [[TwitterRequest alloc] init];
t.username = #"****";
t.password = #"****";
[twitterMessageText resignFirstResponder];
loadingActionSheet = [[UIActionSheet alloc] initWithTitle:#"Posting To Twitter..." delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[loadingActionSheet showInView:self.view];
[t statuses_update:twitterMessageText.text andLat:latitude andLong:longitude delegate:self requestSelector:#selector(status_updateCallback:)];
twitterMessageText.text=#"";
}
#end
So for cases that you do not want to tweet either do not register the listener, remove the listener or add some logic to the TweetListener to know when it is appropriate to tweet.