I'm new to programming and obj-c and currently working on a map based iphone app which will locate different sport facilities. I want each pin to show a different overlay, for instance a picture overlay will do fine, I'll add pics into the resource folder and I want each pin to reveal a different picture by clicking it. My example only includes one pin with its cordinates.
Now, I have now clue where to start, hope u can help me out!
thanks in advance :)
Here's my code:
[mapView addAnnotation:[MapLocation mapLocationtWithTitle:#"Beckomberga Sim och Sporthall" subtitle:#"Söderberga Allé 80" andCoordinate:(CLLocationCoordinate2D){ 59.35817, 17.89740 }]];
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MapLocation class]])
{
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"PinAnnotation"];
pin.canShowCallout = YES;
pin.animatesDrop = NO;
pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pin.pinColor = MKPinAnnotationColorRed;
pin.pinColor = MKPinAnnotationColorGreen;
[pin autorelease];
return pin;
}
return nil;
}
Viktor,
Here is what you need to do:
Create a subobject of MKAnnotation that will represent your locations, SportsFacilityLocation
That object will contain title, subtitle, and location fields. This is to conform to the MKAnnotation protocol
Next you need an object that will be a subclass of MKAnnotationView, SportsFacilityMapView.
Finally in your viewForAnnotation delegate method you need to check each annotation type
and from that annotation type you will determine to return your SportsFacilityMapView
Check the docs on how to implement the Annotation and then AnnotationView. I have some example code at home that I will post later if you need it. Good Luck!
Related
I am working on location based application in which i need to move MKAnnotation Pin as per the change location. It means as user change location from once place to other the Annotation should be moved.
This is my code of annotation:
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mV dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if (pinView == nil)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
pinView.enabled = YES;
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.canShowCallout = YES;
}
return pinView;
}
It drops the pin on the current location but when i move with device the location changed & also MKPolyline i have implement but Pin stays there.
see this image :
You can see in this the green pin is the start point & the other side is the current point. So the pin should be on the current point thats what i want.
I have searched & tried few of the solutions of stack but not able to solve my issue.
Any suggestions & help will be highly appreciated.
Thanks in advance.
I got the solution from #AnnaKarenina suggestions thank you so much.
What i have done is make my MKPinAnnotationView global & then :
pinView.annotation.coordinate = newLocation.coordinate;
This line i added into didUpdateToLocation method which allows annotation to get new location every time.
Thanks again.
I have created the following method for determining the view for my annotations in a map view.
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
MKPinAnnotationView *pin;
if ([annotation isKindOfClass:[AnnotationsWithIndices class]])
{
int i = [(AnnotationsWithIndices *)annotation index];
if (i > currentCheckpointIndex )
{
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"unvisited"];
if (!pin)
{
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"unvisited"];
}
[pin setPinColor:MKPinAnnotationColorRed];
}
if (i == currentCheckpointIndex)
{
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"current"];
if (!pin)
{
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"];
}
[pin setPinColor:MKPinAnnotationColorGreen];
}
if (i < currentCheckpointIndex)
{
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"visited"];
if (!pin)
{
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"visited"];
}
[pin setPinColor:MKPinAnnotationColorPurple];
}
[pin setAnimatesDrop:YES];
return [pin autorelease];
}
else
return nil;
}
The idea is that I want the different annotation views (pins) be of different colors depending on whether the user has visited them to signal which annotation to visit next.
This code works fine, but I have a few questions about it which I hope someone can answer.
Firstly, the MKPinAnnotations are dequeued from a map view and reused whenever possible. In the line doing so (which I have found in multiple blogs and forums)
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"unvisited"];
I understand that the return value of the dequeueReusableAnnotationViewWithIdentifier: is an instance of MKAnnotationView, whereas pin is a pointer to an instance of MKPinAnnotationView (which is a subclass o MKAnnotationView). This, I guess, is why there is a 'cast' seemingly going on with the prefix (MKPinAnnotationView *) in front of the method call. Is this really a cast and in this case, is it not dangerous since the MKPinAnnotationView contains more instance variables (than MKAnnotationView) and hence more space in memory?
I have tried to find some information about this, but nowhere I have not found anyone explaining this in particular.
Furthermore, the pointer annotation is either of class MKUserLocation or of my own custom class AnnotationsWithIndices conforming to the MKAnnotation protocol. Now, in order to determine which color the annotation view should have I have added an instance variable called index into the AnnotationsWithIndices class. Now, when I call the getter for the index I write
int i = [(AnnotationsWithIndices *)annotation index];
Now, I basically have the same question about this. Is there a cast going on here or is it just to let the compiler know that it is ok to send the message index to annotation? I guess that the compiler expects annotation to be an id whereas it really is a pointer to an instance of AnnotationsWithIndices.
Of course I know that this is the case since the annotation will be of my custom class, and I also check this explicitly to be sure. Is the (AnnotationsWithIndices) there only to signal to the compiler that this is OK?
I have also tried to find information about this without luck.
I am very thankful for any answers on this.
In my Application I have to show the google map along with pin images. I have to place two images according to the condition(branch,atm).In viewForAnnotation method I am doing code for the same,in NSLog I am getting the correct output but annotation images aren't placing properly.
Images are placing inconsistently.Here is my code.
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
NSString* identifier = #"Pin";
MKAnnotationView* annView = [searchMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
AddressAnnotation *delegate = annotation;
Location *newLoc = [searchData objectAtIndex:countATMandBranch];
if (annView == nil) {
annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"cell"]autorelease];
annView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if(newLoc.isATM == YES)
{
annView.image = [UIImage imageNamed:#"map_atmicon.png"];
}
else if(newLoc.isBranch == YES)
{
annView.image = [UIImage imageNamed:#"map_branchicon.png"];
}
//annView.enabled = YES;
annView.tag = mapView.tag;
annView.canShowCallout =YES;
}
countATMandBranch++;
return annView;
}
If any one aware of this kind of issue please reply to my question.
This might be an offset issue.
When you use a custom image for an MKAnnotationView it will by default position it in the center. If you are using a custom 'pin' image this isn't what you want - you want the bottom of the pin to point to the location, rather than the center. If you don't change the offset, when you zoom in/out the position of the annotation will appear to change in comparison to where you think it should be.
You should therefore make sure you've set an appropriate centerOffset on your annotation view. I don't see you setting it in the code above, so unless you want your image to be centered exactly on the coordinates required this is probably what's causing it.
please help, this question has been asked so many times before, but peoples suggestions have no effect on my outcome, all i want, is the pin and blue circle (Accuracy) to be shown on the map, here is my implementation. - oh, im using an iPhone device - im not in the simulator
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
NSLog(#"View for Annotation is called");
if (NSClassFromString(#"MKUserLocation")==[annotation class]) {
return nil;
}
if (annotation == mapView.userLocation) {
return nil;
}
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorGreen;
UIButton * btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annView.rightCalloutAccessoryView = btn;
annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
pinDropped = TRUE;
return annView;
}
cheers in advance.... bloody thing
If you're using the Simulator then you're likely encountering the not-well-known difference in the way that CoreLocation and MapKit figure your current position.
In the Simulator
CoreLocation will always use Apple's headquarters in Cupertino, California, USA as your current location. This is where the blue dot will always appear on the map.
MapKit will always use something approximating your actual current location using Apple's database of IP address and WiFi hotspot information. This is where the map will center if you tell it to use your current location.
As a result, the map will center on your current location but the blue dot will be over in Cupertino.
On an iOS Device
CoreLocation puts the blue dot on something approximating your actual current location.
MapKit centers the map on something approximating your actual current location.
As a result you'll see the blue dot in the center of the map when using an actual iOS device.
This bit of knowledge can save a lot of stress. :)
just in case someone was wondering, this also works:
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
This works in my code
if(annotation == mapView.userLocation){
return nil;
}
Try that and let us know
make sure implemented [mapview addAnnotation:annotation];
thanks Anna for the reminder.
I have a MKMapView in my app with several pins on it and I'd like to set different colors for each pin. My view controller is implementing MKMapViewDelegate and I've defined viewForAnnotation method.
- (MKAnnotationView *) mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>) annotation {
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:#"pin"];
annView.pinColor = MKPinAnnotationColorGreen;
return annView;
}
It works fine and changes pin color to green. However the color is changed for all pins and I'd like to color them with several colors (based on some criteria I'd define, lets assume I want to have odd pins green and even pins yellow or something as simple as that). How can this be achieved?
I've solved this issue by using images instead of pinColor. This way I can have as many pins as I want.
if(annotation.fillsYourCriteria)
annView.pinColor = MKPinAnnotationColorGreen;
else
annView.pinColor = MKPinAnnotationColorYellow;
return annView;
Something as simple as that?
I have met the same issue then I solved by using this code
if([[pinView.annotation title] isEqualToString:#"Current Location"])
{
pinView.pinColor = MKPinAnnotationColorRed;
}
else
{
pinView.pinColor = MKPinAnnotationColorPurple;
}