Reputation: 1080
I have a list of objects and each of those has a title, name, description, latitude, longitude and address. Is it possible to show this objects as MKAnnotations? I've been stuck with this for hours now. When I tried to make the objects have a CLLocationCoordinate2D I kept getting the error about latitude or longitude not being assignable.
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface Oficina : NSObject <MKMapViewDelegate>
@property (nonatomic, readwrite) CLLocationCoordinate2D oficinaCoordinate;
@property (nonatomic, strong) NSString *oficinaCiudad;
@property (nonatomic, strong) NSString *oficinaEstado;
@property (nonatomic, strong) NSString *oficinaTitulo;
@property (nonatomic, strong) NSString *oficinaTelefono;
@property (nonatomic, strong) NSString *oficinaLatitud;
@property (nonatomic, strong) NSString *oficinaLongitud;
@property (nonatomic, strong) NSString *oficinaID;
@property (nonatomic, strong) NSString *oficinaDireccion;
@property (nonatomic, strong) NSString *oficinaHorario;
@property (nonatomic, strong) NSString *oficinaTipoDeOficina;
@property (nonatomic, strong) NSString *oficinaServicios;
@property (nonatomic, strong) NSString *oficinaTipoDeModulo;
@end
So after consuming an internet service I get around 70 of these objects. Now I want to be able to turn each of those into a map annotation. This is one of the ways I've tried to assign the latitude but I get the error "Expression not assignable"..
currentOffice.oficinaCoordinate.latitude = [parseCharacters floatValue];
Where currentOffice is an instance of my custom object.
Upvotes: 2
Views: 1157
Reputation: 30549
This is very simple, just loop your objects array and create a MKPointAnnotation
with a coordinate and in your desired format the title and subtitle. Then add those to the map via the addAnnotation
method and pins will appear on the map.
for(Event *event in events){
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(event.lat, event.lon);
MKPointAnnotation *point = [MKPointAnnotation.alloc initWithCoordinate:coordinate title:event.name subtitle:event.venue.name];
[self.mapView addAnnotation:point];
}
If you aren't happy with how the default pin looks or behave then you can create a custom pin by implementing viewForAnnotation
but you have to be careful that you support all the different kinds of annotations on the map not just the ones you created, e.g. the annotation for user's current location.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
if([annotation isKindOfClass:MKPointAnnotation.class]){
MKPinAnnotationView *view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomPin"];
if(!view) {
// create our custom pin view
view = [MKPinAnnotationView.alloc initWithAnnotation:annotation reuseIdentifier:@"CustomPin"];
view.canShowCallout = YES;
view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}else{
// update the previously created custom pin
view.annotation = annotation;
}
return view;
}
else if([annotation isKindOfClass:MKUserLocation.class]){
return nil; // use the default view for user location
}
return nil; // use the default view for any other annotations
}
Upvotes: 0
Reputation: 1080
The way to get the object details for the MKAnnotation that was tapped was to add:
id<MKAnnotation> selectedOffice = view.annotation;
to the delegate method
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { }
in my specific case my MKAnnotation was a custom object called Oficina, so I just passed it to my new view controller like this:
showOfficeDetail = (Oficina *)selectedOffice;
Upvotes: 0
Reputation: 1083
Here is a bit of sample code of how i came to tackle this problem. First loading the mapView annotation array:
CLLocationCoordinate2D location;
Annotation *myAnn;
if (!self.locationsMutableArray) self.locationsMutableArray = [NSMutableArray array];
NSMutableArray *tmpMutableArray = [NSMutableArray array];
for (NSDictionary *subArr in arr)
{
myAnn = [[Annotation alloc] init];
myAnn.address = [NSString stringWithFormat:@"%@, %@, %@, %@",
[subArr objectForKey:@"address"],
[subArr objectForKey:@"city"],
[subArr objectForKey:@"state"],
[subArr objectForKey:@"zip"]];
location.latitude = [[subArr objectForKey:@"lat"] doubleValue];
location.longitude = [[subArr objectForKey:@"lon"] doubleValue];
myAnn.coordinate = location;
myAnn.title = [subArr objectForKey:@"name"];
myAnn.subtitle = [subArr objectForKey:@"siteSpecialtyCategory"];
myAnn.siteType = [subArr objectForKey:@"siteType"];
myAnn.phoneNumber = [subArr objectForKey:@"phoneNumber"];
[tmpMutableArray addObject:myAnn];
}
[self.locationsMutableArray addObject:tmpMutableArray];
[self.mapView addAnnotations:array];
All it really is, is you need to create a custom subclass of MKAnnotationView
mine was called Annotation
. It also has to conform to the <MKAnnotation>
protocol and you can add them to your map view as custom annotations.
Make your Oficina
header file start like this:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface Oficina : MKAnnotationView <MKAnnotation>
@property (nonatomic, readwrite) CLLocationCoordinate2D oficinaCoordinate;
@property (nonatomic, strong) NSString *oficinaCiudad;
@property (nonatomic, strong) NSString *oficinaEstado;
@property (nonatomic, strong) NSString *oficinaTitulo;
@property (nonatomic, strong) NSString *oficinaTelefono;
@property (nonatomic, strong) NSString *oficinaLatitud;
@property (nonatomic, strong) NSString *oficinaLongitud;
@property (nonatomic, strong) NSString *oficinaID;
@property (nonatomic, strong) NSString *oficinaDireccion;
@property (nonatomic, strong) NSString *oficinaHorario;
@property (nonatomic, strong) NSString *oficinaTipoDeOficina;
@property (nonatomic, strong) NSString *oficinaServicios;
@property (nonatomic, strong) NSString *oficinaTipoDeModulo;
@end
Upvotes: 1
Reputation: 98
Its possible to show title, name, description, latitude, longitude and address as MKAnnotations.
Have you tried to change the coordinate property to 'assign'?
@interface MyAnnotation : NSObject<MKAnnotation>
{
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *name;
NSString *description;
}
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *description;
Upvotes: 2