A question about MKPinAnnotationView - iphone

Wish to specify the the color of a map pin other than the default red. From documentation, the MKPinAnnotationView class has a pinColor property where we can set the color. My question is : what is the proper way to associate this pinColor property with an annotation object?
Wish that somebody knowledgable on this could help ...

i think only three colors are defined for pinColor property.
enum {
MKPinAnnotationColorRed = 0,
MKPinAnnotationColorGreen,
MKPinAnnotationColorPurple
};
typedef NSUInteger MKPinAnnotationColor;
Here's the method to define it.
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:MyAnnotationIdentifier] autorelease];
customPinView.pinColor = MKPinAnnotationColorPurple;

I hope I understand you question correctly.
I guess that would be part of your logic and that there's no one "correct" answer.
In one app I might have a plist containing definitions of all the objects in my app and their properties. In another more simple app I might just specify the color based upon an index when it's created for example.
If you just want to know how to set a property then follow Shrey's advice above

Related

Updating image in MKAnnotationView

I am writing an application that displays a thumbnail from a server in the leftCalloutAccessoryView. Before I actually get the image, I display a placemark image. Once the photo is downloaded, a method is called and I want to update that image without removing the original annotation and placing another. I just wan the image to switch from the placeholder to the downloaded thumbnail. Below is the code that does not work, but if someone could let me know if I'm on the right track, that would be great.
MyAnnotationClass *annotation=[[MyAnnotationClass alloc] initWithCoordinate:item.location];
[annotation setItem:item];
if(item.title){
annotation.name=item.title;
}
else{
annotation.name=#"no title";
}
[annotation setDescription:[[NSString alloc] initWithFormat:#"Views:%d Likes:%d Comments:%d",item.views,item.likes,item.comments]];
[annotation setImage:[[photo.thumb copyWithDimensions: CGSizeMake(32.0, 32.0)] autorelease]];
MKAnnotationView *av=[__mapView viewForAnnotation:annotation];
UIImageView *imageView=[[UIImageView alloc] initWithImage:annotation.image];
imageView.frame=CGRectMake(0.0, 0.0, 32.0, 32.0);
av.leftCalloutAccessoryView=imageView;
[annotation release];
I have been looking around here for quite sometime, but nothing that I can find will do what I need. Thanks
If the annotation is already on the map and you want to update it, don't create a new one.
Instead, find the annotation you want to update in the map view's annotations array and update its properties. Then call viewForAnnotation: on that existing annotation and update the leftCalloutAccessoryView.
Also, make sure the viewForAnnotation delegate method has logic that sets the leftCalloutAccessoryView to either the placeholder image or the actual image by checking the annotation's properties (and not always the placeholder image).
This other question has some sample code that may help.

iPhone MKAnnotation with an ID for database content

Im trying to use the MKMap API and integrate a database table id so I can click a button detail disclosure to send the user to another page with further information. Ive been all over teh MKMapKit on the Apple site to find some property or method to help me with this and went over a few tutorials with no answers.
Ive tried to attach the id into the subtitle context so I can retrieve it in the MKAnnotationView where I make my MKPinAnnotationView and add teh button to the rightCalloutAccessoryView. It errors out and doesnt want to work.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"mkpin"];
annView.animatesDrop = YES;
annView.canShowCallout = YES;
UIButton *disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annView.rightCalloutAccessoryView = disclosureButton;
return annView;
}
I used this technique for an individual pin on a map and it seemed to work but I didnt require an id...
When I try to get the subtitle of the annotation it kills the app. I know the (id)annotation is an integer but I dont know how to manipulate this information. This function above I think is called after my code:
[mapView addAnnotations:markers]; //where markers is an array of title, subtitle aka id
Any help would be greatly appreciated.
The subtitle property is for a subtitle, not a database id. No good can come from abusing it in that way. Even if you could get it to work, it's a horrible approach.
All you have to do is give your annotation class an appropriate property to store your id. When you are passed the annotation, you can access it from there by casting to your annotation class. When you are passed the annotation view in other delegate methods, you can access the annotation through its annotation property.

issue with with MKAnnotation image property

I am implementing a MKMapView based application. In that I am using a custom image instead of displaying a pin by using MKAnnotationView.Image property. It is not working. It keeps showing the standard pin in red but not the image I am pointing too. Any ideas?
- (void)setPin:(MKPinAnnotationView *)aPin forAnnotation:(id <MKAnnotation>)anAnnotation {
if (anAnnotation == self.userAnnotation) {
aPin.image = [UIImage imageNamed:#"youarehere.png"];
aPin.opaque = NO;
aPin.pinColor = MKPinAnnotationColorRed;
}
}
If you use MKPinAnnotationView like you are then you don't get to set the image only the pinColor. MKPinAnnotationView only has pinColor and animatesDrop as the properties.
You want to use the parent class MKAnnotationView. It will let you set the image.
Read the Class Reference for each and it will make sense. This is one of the times that Objective-C makes me crazy because when you are reading those long class names in the docs, it's easy to scan right over the "Pin" variation in the class name.

Annotation Sub Class custom initWithCoordinate

I've subclassed MKAnnotation so that i can assign objects to each annotation, this is so that when the rightCalloutAccessoryView is clicked i can push a navigation controller with the object passed to it and display the objects data in another view.
This all works great apart from one thing, i've extended upon initWithCoordinate like so:
-(id)initWithCoordinate:(CLLocationCoordinate2D)coord andObject:(NSManagedObject *)object {
[self setPlace:object];
coordinate = coord;
title = [place valueForKey:#"name"];
subtitle = [place valueForKey:#"address"];
return self;
}
Although everything is working great i'm recieving the warning:
NO '-initWithCoordinate:andObject:' method found
Which means i'm doing something wrong somewhere, what is the correct way to go about adding upon initWithCoorinate?
Put the prototype -(id)initWithCoordinate:(CLLocationCoordinate2D)coord andObject:(NSManagedObject *)object in .h file.

Using the value of a string to determine the instance of a class

I have a switch statement similar to this one:
switch (number)
{
case 1:
if (imageView1.hidden == NO)
{
imageView1.hidden = YES;
} else
{
imageView1.hidden = NO;
}
break;
case 2:
if (imageView2.hidden == NO)
{
imageView2.hidden = YES;
} else
{
imageView2.hidden = NO;
}
break;
And so forth and so on.
My question is how do I use a string with a value say "imageView1" and use that to access the instance of my imageView class instead of having a different case for each instance of imageView? I know it muse be similar to creating an NSPath from a string or something like that, but I'm just not sure where to look or what it would be called.
Thanks in advance for any help!
I don't disagree with those who are concerned about the design, if this is actually the code. I will assume, however, that you are only posting a generalized version of your question. And since this is an important concept in Objective-C, so we should talk about it.
You can access an object's properties by name using Key Value coding, and the routine -valueWithKey:.
NSString *nameOfView = #"imageView1";
[[self valueForKey:nameOfView] setHidden:YES];
This will, in order, look for a method called -imageView1, an ivar named imageView1 and finally an ivar named _imageView1. This technique is very heavily used in Cocoa, and is important to understand. This is one of the many reasons we name things carefully, and yet another reason that we make accessors that handle memory management for us. Search the docs for "Key-Value Compliance" for more information.
Now for this specific case, I would tend towards something more like JimG's solution, using an NSArray of views, so I can loop through them and turn on or off the ones I want based on their index. But I can imagine a lot of cases where that wouldn't be appropriate, and KVC may be.
Why not put the instances in an NSArray and index into that?
NSArray *views = [NSArray arrayWithObjects: imageView1, imageView2, nil];
NSImageView *iview = [views objectAtIndex: number];
Also, you could consider something like:
iview.hidden = ! iview.hidden;
[Edit: missing asterisks, oops]