Based on my different enum values, I need to display the different images in my mapview.
How I can do that ? I am new to iOS development. Please anybody help me.
You need to use "ViewForAnnotation" delegate method in your view Controller.
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
{
if( [annotation isKindOfClass:[Annotation class] ] )
{
static NSString * AnnotationID = #"Annotation";
Annotation * pannotation = (Annotation *)annotation;
//if( pannotation == nil ) return nil;
MKAnnotationView *annotationView = nil;
annotationView = [self.mMapView dequeueReusableAnnotationViewWithIdentifier:AnnotationID];
if( annotationView == nil )
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationID] autorelease];
}
UIImage * flagImage = nil;
if(Your enum Values)
flagImage = [UIImage imageNamed:#"darkgreendot.png"];
else if(....)
flagImage = [UIImage imageNamed:#"orangedot.png"];
else
flagImage = [UIImage imageNamed:#"bluedot.png"];
CGRect resizeRect;
resizeRect.size = flagImage.size;
resizeRect.origin = (CGPoint){0.0f, 0.0f};
UIGraphicsBeginImageContext(resizeRect.size);
[flagImage drawInRect:resizeRect];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
annotationView.image = resizedImage;
return annotationView;
}
}
Hope this helps you.
Related
I have 2 MKPointAnnotation and i want to display them on map with two different pins(MKAnnotationView having image).
// MKPointAnnotation - 1
CLLocationCoordinate2D cordinate;
cordinate.latitude = [_latitudeString doubleValue];
cordinate.longitude = [_longitudeString doubleValue];
MKPointAnnotation *point1 = [[MKPointAnnotation alloc] init];
point1.coordinate = CLLocationCoordinate2DMake(cordinate.latitude, cordinate.longitude);
[self.mapView addAnnotation:point1];
P.S - When i get second MKPointAnnotation i needed self zoom on that area.
// MKPointAnnotation - 2
CLLocationCoordinate2D cordinate;
cordinate.latitude = [_latStr doubleValue];
cordinate.longitude = [_longStr doubleValue];
MKPointAnnotation *point2 = [[MKPointAnnotation alloc] init];
point2.coordinate = CLLocationCoordinate2DMake(cordinate.latitude, cordinate.longitude);
[self.mapView addAnnotation:point2];
//This is my code for MKAnnotationView
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
if ([annotation isKindOfClass:[MKPointAnnotation class]]){
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if(!pinView){
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"annotation"];
pinView.calloutOffset = CGPointMake(0, 0);
}
else{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
What i need to change in the viewForAnnotation method?
For example, you can create subclass of MKPointAnnotation.
#interface SecondAnnotation: MKPointAnnotation
#end
#implementation SecondAnnotation
#end
Add SecondAnnotation to the mapView.
// MKPointAnnotation - 2
...
SecondAnnotation *point2 = [[SecondAnnotation alloc] init];
point2.coordinate = CLLocationCoordinate2DMake(cordinate.latitude,
cordinate.longitude);
[self.mapView addAnnotation:point2];
You can use different MKAnnotationView with the following code.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
if ([annotation isKindOfClass:[MKPointAnnotation class]]){
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if(!pinView){
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"Annotation"];
pinView.calloutOffset = CGPointMake(0, 0);
}
else{
pinView.annotation = annotation;
}
return pinView;
} else if ([annotation isKindOfClass:[SecondAnnotation class]]){
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if(!pinView){
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"Second"];
pinView.calloutOffset = CGPointMake(0, 0);
}
else{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
Writing the viewForAnnotation as below solved my problem -
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
if ([annotation isKindOfClass:[MKPointAnnotation class]]){
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if(!pinView){
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"annotation"];
pinView.calloutOffset = CGPointMake(0, 0);
}
else{
pinView.annotation = annotation;
if ([annotation isKindOfClass:[SecondAnnotation class]]) {
pinView.image = [UIImage imageNamed:#"range"];
}
else{
pinView.image = [UIImage imageNamed:#"annotation"];
}
}
return pinView;
}
return nil;
}
As user is moving i wanted to plot another mkannotation on his old position which is different than current annotation in objective-c
for which I have written code
-(void)plotDotted:(double)latitude :(double)longitude
{
_busOldAnnotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[self.sampleMap addAnnotation:_busOldAnnotation];
}
-(void)plotPoint:(double)latitude :(double)longitude
{
_busAnnotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[self.sampleMap addAnnotation:_busAnnotation];
}
Annotation Delegate
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *Identifier = #"driverView";
MKAnnotationView* myAnnotation = [self.sampleMap dequeueReusableAnnotationViewWithIdentifier:Identifier];
if (myAnnotation == nil)
{
myAnnotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier];
//myAnnotation.enabled = YES;
}
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(_latituDouble, _longitudeDouble);
if (coordinate.latitude == _latituDouble && coordinate.longitude == _longitudeDouble)
{
myAnnotation.image = [UIImage imageNamed:#"bus_icon.png"];
}
else if (_busOldAnnotation)
{
myAnnotation.image = [UIImage imageNamed:#"blue_dot.png"];
}
return myAnnotation;
}
Called Functions
//1. Remove
[self removeAnnotation];
//3. Add new
[self plotPoint:latitudeDouble :longitudeDouble];
//2. Add Old
[self plotDotted:_latituDouble :_longitudeDouble];
//4. Assign that coordinate to global
_latituDouble = latitudeDouble;
_longitudeDouble = longitudeDouble;
[self.sampleMap reloadInputViews];
Everything is working fine that , user is moving on my map ,
Removing previous location,
but not able to add blue_dot image after that user is moving
Use this and see if it works
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(_latituDouble, _longitudeDouble);
if (coordinate.latitude == _latituDouble && coordinate.longitude == _longitudeDouble)
{
static NSString *Identifier1 = #"driverView";
MKAnnotationView* myAnnotation = [self.sampleMap dequeueReusableAnnotationViewWithIdentifier:Identifier1];
if (myAnnotation == nil)
{
myAnnotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier];
//myAnnotation.enabled = YES;
}
myAnnotation.image = [UIImage imageNamed:#"bus_icon.png"];
return myAnnotation;
}
else if (_busOldAnnotation)
{
static NSString *Identifier2 = #"driverView2";
MKAnnotationView* myAnnotation = [self.sampleMap dequeueReusableAnnotationViewWithIdentifier:Identifier2];
if (myAnnotation == nil)
{
myAnnotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier];
//myAnnotation.enabled = YES;
}
myAnnotation.image = [UIImage imageNamed:#"blue_dot.png"];
return myAnnotation;
}
return nil;
}
I want to show different annotations at each pin,with my image named "01.png" to "08.png".
I set integer a random number from 1~8
integer = arc4random() % 8 + 1;
then set the method -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
if(annotation == mapView.userLocation){
return nil;
}
NSString *identifier = #"Store";
MKAnnotationView *result = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(result == nil){
result = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
result.annotation = annotation;
}
NSString * imageName = [NSString stringWithFormat:#"0%i",integer];
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"%#",imageName]];
result.image = image;
return result;
but the mapView show the same annotations,it will show different annotations at each time I open the apps.
How to show different annotations at each pin?
Thank you very much!
You must put the randomization inside the annotation method. A variable has one value until it is changed, it does not get a new random value every time you read from it.
I'm trying to replace the MKAnnotationView image depending on an object value, the code is executed but the images are randomly assigned so they are not matched with the correct values.
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(EventAnnotation *)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.canShowCallout = YES;
annotationView.image = [self setImageByType:annotation];
annotationView.draggable = NO;
return annotationView;
}
return nil;
}
setImageByType method:
- (UIImage*)setImageByType:(EventAnnotation *)annotation{
//Set annotation image depending on its type
UIImage *image = [[UIImage alloc]init];
NSString *type = annotation.type;
if ([type isEqualToString:#"event"]) {
image = [UIImage imageNamed:#"geolocalization_events"];
}else if ([type isEqualToString:#"show"]){
image = [UIImage imageNamed:#"geolocalization_shows"];
}else if ([type isEqualToString:#"culture"]){
image = [UIImage imageNamed:#"geolocalization_culture"];
}else if ([type isEqualToString:#"eat"]){
image = [UIImage imageNamed:#"geolocalization_eat"];
}else if ([type isEqualToString:#"drink"]){
image = [UIImage imageNamed:#"geolocalization_drink"];
}else if ([type isEqualToString:#"cybercafe"]){
image = [UIImage imageNamed:#"geolocalization_cybercafe"];
}
UIImage *finalImage = [self imageWithImage:image scaledToSize:CGSizeMake(50, 50)];
return finalImage;
}
resize the image:
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
//Resize annotation image
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
I would say the code is executed faster than the images are assigned to the views. Any ideas?
Option 1
Try changing this line:
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
To this:
NSString* AnnotationIdentifier = annotation.type;
Option 2:
After this line:
MKAnnotationView *annotationView = [mapview dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
Add this line:
annotationView.image = [self setImageByType:annotation];
I am parse Json with coordinates and download individual profile image for each annotation view. When I do zoom or move on map I see what images replaced on wrong places. For example I have annotation view with coordinates 111.1111, 111.1111. First time image and coordinate is correct, but after moves/zoom/reopen tab with map I see other annotation view with coordinates 222.222, 222.222 with image which is suitable for 111.111, 111.1111.
(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *identifier = #"SYLocationItem";
if ([annotation isKindOfClass:[SYLocationItem class]]) {
MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = NO;
SYJabberClient *client = [SYJabberClient sharedClient];
[client retrieveProfileForUserWithEmail:[(SYLocationItem*)annotation email]
withSuccessBlock:^(NSDictionary *dict, NSError *error) {
if (dict) {
UIImage *image = [dict objectForKey:#"imageFile"];
UIImage *displayImage = [UIImage circularScaleNCrop:image
withRect:
CGRectMake(0.0f,0.0f,30.0f,30.0f)];
annotationView.image = displayImage;
}
}];
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
In this code now I get image from local, but if downloading images I have same issue.