Can't be changed pin color when I change segement in mkMapView - iphone

I have some problem regarding Annotations in mapView. Lets have one glance on my requirement.
I want to give choice to user to choose location for meeting.
There are two options.
1) I should give list of near by data
Or
2) He can drag and drop pin anywhere he wants !
For that I have created one segment.
First index for near by data
and
Second index for dropping a pin.
For First option ("near by") I need to fetch near by data from location of Seller, location of Buyer and midpoint between seller and buyer. So I call google api and get data by passing latitude and longitude three times. There is no issue when I get data first time. My array fill up with all data (included 3 responses) and pin color also changes as per requirement.
Buyer (Red Color)
Seller ( Purple)
Mid Point (Green)
Now when I click on drop pin all data are removed from array and one pin is dropped on map.
Till now it works fine !
But when you again click on "near by", Problem starts ! No doubt it gives me data as I want but pin colors don't maintained.
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([segmentND selectedSegmentIndex]==0) {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString* BridgeAnnotationIdentifier = #"bridgeAnnotationIdentifier";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)
[myMapView dequeueReusableAnnotationViewWithIdentifier:BridgeAnnotationIdentifier];
if (!pinView)
{
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease];
switch (self.pinColor) {
case 0:
{
customPinView.pinColor = MKPinAnnotationColorPurple;
}
break;
case 1:
{
customPinView.pinColor = MKPinAnnotationColorRed;
}
break;
case 2:
{
customPinView.pinColor = MKPinAnnotationColorGreen;
}
break;
default:
break;
}
customPinView.canShowCallout = YES;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
else {
// Code of dragging dropping pin. It works Fine.s
}
}
I am attaching image for more idea.
Please give me solution or any another way to implement it. Remember Pin color is compulsory to differentiate Seller Buyer and Midpoint !

The trouble with your current approach is that self.pinColor doesn't change according to which annotation the map is needing a view for. It can and will call viewForAnnotation when ever it feels like it. Maybe the map has been scrolled around and one pin has just come back into view. Maybe the app was put into the background and is just being brought back into view by the user. What ever the reason you need to analyze the annotation is is passing in to determine which pin colour to use in the view. What object are you using for your annotation? If it was HSAnno and it had a property called pinColor you'd do something like this instead of your switch statement.
HSAnno* currentAnno = (HSAnno *)annotation;
pinView.pinColor = currentAnno.pinColor;
That way no matter what annotation needed to be redrawn viewForAnnotation would always return the right coloured pin.

You set your pincolor in that code part when no reusable pin exists.
if (!pinView)
....
customPinView.pinColor = MKPinAnnotationColorPurple;
....
}
When viewForAnnotation is called and reusable pins are found they are used. There is where the wrong color pin is taken.
Set your pincolor in the
else
{
pinView.annotation = annotation;
}
part and it should work fine.

Think its got mistaken here
else
{
pinView.annotation = annotation;
}
return pinView;
Correct it to
else
{
pinView.annotation = annotation;
return pinView;
}

Here's I little modified your code & MKMapView delegate. Previously you've changing pin color inside if that make it to call only for once when first time MKMapView loads.
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString* BridgeAnnotationIdentifier = #"bridgeAnnotationIdentifier";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)
[mapView dequeueReusableAnnotationViewWithIdentifier:BridgeAnnotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease];
}
else
{
pinView.annotation = annotation;
}
switch (self.pinColor) {
case 0:
{
pinView.pinColor = MKPinAnnotationColorPurple;
}
break;
case 1:
{
pinView.pinColor = MKPinAnnotationColorRed;
}
break;
case 2:
{
pinView.pinColor = MKPinAnnotationColorGreen;
}
break;
default:
break;
pinView.canShowCallout = YES;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
return pinView;
}
return pinView;
}
P.S. I've removed your first UISegment condition to check at my side, please add it as is, when you implement.

Related

User location image pin disappears most of time

i Am using following code
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([[annotation title] isEqualToString:#"Current Location"] )
{
MKAnnotationView *anView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentPin"];
anView.image = [UIImage imageNamed:#"pin_green.png"];
anView.canShowCallout = true;
anView.enabled = true;
return anView;
}
The issue is, it randomly disappears and appears again. Giving a very bad user experience. Any way to fix this?
There are several suspect things about this code:
You're not using dequeue, as someone has pointed out. In particular, the problem here is that you are making a new view every single time, rather than checking to see whether a new view needs making.
You are forgetting the key step, namely, to associate the view with the annotation.
Here is the canonical structure of a simple viewForAnnotation: implementation where we supply our own view:
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView* v = nil;
if ([annotation.title isEqualToString:#"Current Location"]) {
static NSString* ident = #"greenPin";
v = [mapView dequeueReusableAnnotationViewWithIdentifier:ident];
if (v == nil) {
v = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:ident];
v.image = [UIImage imageNamed:#"pin_green.png"];
v.canShowCallout = YES;
}
v.annotation = annotation;
}
return v;
}
Since that code works for me, I'd suggest you start with it and tweak it as necessary.
By the way, you do NOT need this method just to get a green pin! You do know that, right? iOS will give you a green pin (MKPinAnnotationColorGreen).
You should use MKMapView's dequeueReusableAnnotationViewWithIdentifier: and see if you get a view back before creating a new one with initWithAnnotation:reuseIdentifier::
MKAnnotationView *anView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"currentPin"];
if (!anView) {
anView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentPin"];
anView.image = [UIImage imageNamed:#"pin_green.png"];
anView.canShowCallout = true;
anView.enabled = true;
}
return anView;
That said, I'm not entirely sure this is the cause of your problem.

Show hotels (and near by places) by appropriate icon on Map in iPhone App

I am using Google places API for getting places near by the predefined location.
It works fine. I am supposed to show PushPins for each place. For now, I am using default red pushpins for each place.
Now, I want to show appropriate icon for each place, for eg;
for Hotels, Restaurants, etc....
On android, my colleague developers do the same thing, by using the Google API response.
In iPhone, I am not able to find any such help. Is there any way to do that on iPhone ???
This might not address your question. But, some work-around.
I have came across the similar problem.
I did categorized the data, and showed notations according to that, along with the condition.
Hope this code gives you some idea about how i did it.
-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
MKPinAnnotationView *view = nil;
if (annotation != mapView.userLocation) {
view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"myAnnotationIdentifier"];
if (!view) {
view = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"myAnnotationIdentifier"];
CustomClassAnnotation *desclosureButton = [[CustomClassAnnotation alloc] initWithFrame:CGRectMake(0, 0, 29, 31)];
[desclosureButton addTarget:self action:#selector(mapAction:) forControlEvents:(UIControlEventTouchUpInside)];
view.rightCalloutAccessoryView = desclosureButton;
view.canShowCallout = YES;
}
((CustomClassAnnotation *)view.rightCalloutAccessoryView).annotation = annotation;
if (((MapViewAnnotation *)annotation).type == 1) {
view.image = [UIImage imageNamed:#"image_type1.png"];
}
else if (((MapViewAnnotation *)annotation).type == 2) {
view.image = [UIImage imageNamed:#"image_type2.png"];
}
else if (((MapViewAnnotation *)annotation).type == 3) {
view.image = [UIImage imageNamed:#"image_type3.png"];
}
}
return view;
}
Best of luck...

viewForAnnotation problem-Images are not placing properly on google map in iPhone

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.

MKAnnotation shows it's Custom Marker graphic in simulator but not on device

I had this working very early, but then it stopped and I have no idea why. Here is the code:
- (void)updateMarkers:(NSMutableArray *)myAudioLocationVOArray
{
[self cleanupMarkers];
NSLog(#"UPDATE ALL MARKERS");
int tArrayCount = [myAudioLocationVOArray count];
for (int i=0; i< tArrayCount; i = i + 1)
{
AudioLocationVO* tAudioLocVO = [myAudioLocationVOArray objectAtIndex:i];
AudioAnnotation *tNewAnn = [[AudioAnnotation alloc] init];
tNewAnn.coordinate = CLLocationCoordinate2DMake(tAudioLocVO.latitude, tAudioLocVO.longitude);
// add current track if available
tNewAnn.audioLocationVORef = tAudioLocVO;
[self.mapView addAnnotation:tNewAnn];
[tNewAnn release];
}
}
- (void)cleanupMarkers
{
NSLog(#"REMOVE ALL MARKERS");
NSArray *tExistingPoints = self.mapView.annotations;
if ([tExistingPoints count] > 0)
{
[self.mapView removeAnnotations:tExistingPoints];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)myMapView viewForAnnotation:(id <MKAnnotation>)myAnnotation
{
if ([myAnnotation isKindOfClass:[AudioAnnotation class]])
{
AudioAnnotation *tAnnotation = (AudioAnnotation *)myAnnotation;
MKAnnotationView *tNewMarkerView = [[[MKAnnotationView alloc] initWithAnnotation:tAnnotation reuseIdentifier:nil] autorelease];
if(tAnnotation.audioLocationVORef.state == ANNOTATION_STATE_DROPPING)
{
NSLog(#"ADD DROP MARKER");
[tNewMarkerView setImage:[UIImage imageNamed:#"greenmarker.png"]];
tNewMarkerView.draggable = YES;
}
else
{
NSLog(#"ADD NEW MARKER");
[tNewMarkerView setImage:[UIImage imageNamed:#"newMarker.png"]];
tNewMarkerView.draggable = NO;
}
tNewMarkerView.frame = CGRectMake(tNewMarkerView.frame.origin.x,tNewMarkerView.frame.origin.y,20,26);
tNewMarkerView.canShowCallout = YES;
tNewMarkerView.enabled = YES;
// callout button
UIButton *tButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
tNewMarkerView.rightCalloutAccessoryView = tButton;
// cover art and title/subtitle
UIButton *tCover = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if(tAnnotation.audioLocationVORef.trackVO==nil)
{
tAnnotation.title = #"Drop a Track";
tAnnotation.subtitle = #"Choose a track to drop";
[tCover setImage:[UIImage imageNamed:#"preCover.png"] forState:UIControlStateNormal];
}
else
{
tAnnotation.title = tAnnotation.audioLocationVORef.trackVO.songTitle;
tAnnotation.subtitle = tAnnotation.audioLocationVORef.trackVO.artist;
NSLog(#"ADD DATA MARKER %#", tAnnotation.title);
if(tAnnotation.audioLocationVORef.state==ANNOTATION_STATE_DROPPING){
tAnnotation.subtitle = #"Touch submit to Drop";
}
[tCover setImage:[tAnnotation.audioLocationVORef.trackVO getCoverArt] forState:UIControlStateNormal];
}
// make cover enabled to see song detail?
tCover.enabled = NO;
tNewMarkerView.leftCalloutAccessoryView = tCover;
[tCover release];
return tNewMarkerView;
}
return nil;
}
I tried to delete and add again the graphics as assets. I have been playing around a bit with the frame property. So far no luck.
And why the difference between simulator and device. I am using SDK 4.2... on iPhone 4
Make sure the image filenames match exactly with the resource names including upper/lower-case.
For example, if the resource is "GreenMarker.png", then "greenmarker.png" will only work on the simulator and not on the device.
Apple QA1697 (Why doesn't my device load a file that loads fine in the Simulator?) says:
Case-sensitivity: iPhone OS uses a
case-sensitive file system, unlike the
Simulator which uses a
case-insensitive file system by
default. Make sure the
case-sensitivity of resources accessed
within code matches the filename
case-sensitivity.
True, they should, but the Mac is case-preserving but also case-insensitive. The simulator runs on the Mac, so that's what you get.

Several pin colors on same map in MKMapView

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;
}