MKAnnotations not reloading correctly - ios

Having trouble with MKAnnotation. Have a custom pinview and works fine for the first loading. Go to remove pins and then reload same pins they change colors. Im adding pins from two different DB's and works just fine. Once removed and then add each array separately the second array takes the first arrays custom pin instead of the one assigned.
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"pin";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"stores.png"]];
pinView.leftCalloutAccessoryView = profileIconView;
NSString *badgestringss = #"8 reviews";
customBadge1 = [CustomBadge customBadgeWithString:badgestringss
withStringColor:[UIColor whiteColor]
withInsetColor:RGB(255, 51, 0)
withBadgeFrame:YES
withBadgeFrameColor:[UIColor whiteColor]
withScale:1.0
withShining:YES];
[customBadge1 setFrame:CGRectMake(100, 1, 85, 15)];
[pinView.leftCalloutAccessoryView addSubview:customBadge1];
if(setStoreOrShops==NO){
pinView.image = [UIImage imageNamed:#"stores.png"]; //as suggested by Squatch
}
else if (setStoreOrShops==YES){
pinView.image = [UIImage imageNamed:#"shops.png"];
}
else {
[mapView.userLocation setTitle:#"Current Location"];
}
}
return pinView;
}
have searched all over but cant seem to get an example to work or an idea where this is breaking down. Thanks for any help.

I'm not sure what you mean by changing color, as I don't know what your CustomBadge code does or what your images look like. However, the problem could be that you are applying conditional logic inside of your initial setup of the view. Later when dequeReusableAnnotationViewWithIdentifier: actually returns something, it's been configured for something else.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKAnnotationView *pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"default"];
if (pinView == nil) {
// CONFIGURE ONCE
// things that are set up once and never change
}
// CONFIGURE EVERY VIEW
// view configurations that change every pin
}
You need to take the code that sets your images out of the "configure once" section and put it in the "configure for every view" section. Otherwise, every time you make a call to dequeue a reusable view you can get something that is configured incorrectly.

got it fixed this way
MyAnnotation *myAnnot = (MyAnnotation *)annotation;
if (myAnnot.mappin == #"42")
customPinView.image = [UIImage imageNamed:#"shops.png"];
else
customPinView.image = [UIImage imageNamed:#"stores.png"];

Related

AnnotationView mixing up photos and IDs

I have a code for creating annotation view :
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id<MKAnnotation>)myannotation{
MKAnnotationView *view = nil;
view = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"identifier"];
if([myannotation isKindOfClass:[myAnnotation class]]){
if(nil == view) {
view = [[MKPinAnnotationView alloc] initWithAnnotation:myannotation
reuseIdentifier:#"identifier"];
view.canShowCallout = YES;
}
myAnnotation *anns= (myAnnotation*)myannotation;
_annimge=anns.Img;
UIButton *btnViewVenue = [UIButton buttonWithType:UIButtonTypeContactAdd];
[btnViewVenue addTarget:self action:#selector(ButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
btnViewVenue.titleLabel.text=#"GĂ“WNOKURWA";
view.rightCalloutAccessoryView=btnViewVenue;
}
return view;
}
I would like to show image on button press, thats why I signing image property of annotation to _annimge, but it only shows the last image added, no matter which annotation is active, same thing was happening with ID property which I added, it only returned the highest ID (last added).I am new at iOS and trying to fix this issue for way too long. Thanks for help.

MKAnnotationView pin.image incorrect image displayed

I'm having trouble understanding what I'm doing wrong when setting my custom pin images.
Here is my mapView:viewForAnnotation method that I have. As you can see, I want different images to display based on the value in my Location object. For the majority this works, and the correct images are being associated with the correct pins. However, on occasion they are just plain wrong and seem to be randomly assigned.
Any guidance would be appreciated!
EDIT: I've updated my code below in line with latest comments. It's still causing the same behaviour....
- (MKAnnotationView *)mapView:(MKMapView *)MapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
if([annotation isKindOfClass:[ADClusterAnnotation class]])
{
MKAnnotationView * pinView = (MKAnnotationView *)[MapView dequeueReusableAnnotationViewWithIdentifier:#"ADClusterableAnnotation"];
if (pinView == nil)
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"ADClusterableAnnotation"];
} else
{
pinView.annotation = annotation;
}
Location *selectedLocation = [[[(ADClusterAnnotation *) annotation cluster] annotation] annotation];
UIButton *rightCallout = [UIButton buttonWithType:UIButtonTypeCustom];
rightCallout.frame = CGRectMake(0, 0, 23, 23);
rightCallout.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
rightCallout.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
pinView.image = nil;
pinView.canShowCallout = YES;
[rightCallout setImage:[UIImage imageNamed:#"star.png"] forState:UIControlStateNormal];
pinView.rightCalloutAccessoryView = rightCallout;
if (selectedLocation.number.intValue > 4)
{
pinView.image = [UIImage imageNamed:#"image3.png"];
}
else if (selectedLocation.number.intValue >= 1)
{
pinView.image = [UIImage imageNamed:#"image2.png"];
}
else if (selectedLocation.number.intValue < 1)
{
pinView.image = [UIImage imageNamed:#"image3.png"];
}
return pinView;
}
return nil;
}
OK. I've made it much simpler than the starting point, but I've still got the exact same problem! It's is really driving me crazy, I have no idea what I'm doing wrong. Please please can someone help.
btw, I'm using the following for clustering my annotations (I don't know if this is causing issue!): https://github.com/applidium/ADClusterMapView
You are only setting the pinView.image if pinView is hill after trying to dequeue it. Which will work for the first few until the page is full. If you then scroll down the ones on screen go out of view and get reused for the new rows that appear. Because they are pulled from the queue you are not changing their image and you see the image from the rows that have gone away.
Basically you should build a new pinView if you can't dequeue one, but you still need to set the pinView.image either way, so close off the if statement like this.
if (!pinView) {
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation
} reuseIdentifier:#"ADClusterableAnnotation"];

MKAnnotationView custom button image

I am trying to use a custom image on my MKAnnotationView when I use the following code I get no image on my annotation. I have checked in debug to ensure the image is being properly loaded into the UIImage.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"String"];
if(!annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"String"];
UIButton *directionButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *directionIcon = [UIImage imageNamed:#"IconDirections"];
[directionButton setImage:directionIcon forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = directionButton;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
return annotationView;
}
There are two main issues:
The frame of the custom callout button is not set making it essentially invisible.
An MKAnnotationView is being created but its image property (the image of the annotation itself -- not the callout button's) is not set. This makes the whole annotation invisible.
For issue 1, set the button's frame to some appropriate value. For example:
UIImage *directionIcon = [UIImage imageNamed:#"IconDirections"];
directionButton.frame =
CGRectMake(0, 0, directionIcon.size.width, directionIcon.size.height);
For issue 2, set the annotation view's image (or create an MKPinAnnotationView instead):
annotationView.image = [UIImage imageNamed:#"SomeIcon"];
Additionally, you should handle view re-use correctly by updating the annotation property.
Complete example:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"String"];
if(!annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"String"];
annotationView.image = [UIImage imageNamed:#"SomeIcon"];
UIButton *directionButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *directionIcon = [UIImage imageNamed:#"IconDirections"];
directionButton.frame =
CGRectMake(0, 0, directionIcon.size.width, directionIcon.size.height);
[directionButton setImage:directionIcon forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = directionButton;
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
}
else {
//update annotation to current if re-using a view
annotationView.annotation = annotation;
}
return annotationView;
}
In order for the callout to be shown, the annotation must be selected. To do this programmatically, call:
[mapView selectAnnotation:annotation animated:YES];
where annotation is the specific MKAnnotation for which you want a callout displayed.
You'll almost certainly want to put this in - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views.
There are a few caveats to consider, so here are two other posts that have some great answers and relevant discussions:
How to trigger MKAnnotationView's callout view without touching the pin?
Wanted: How to reliably, consistently select an MKMapView annotation

How can i change mapkit annotation detail view background color?

Hi am trying to change the annotation detail view(show in map image) into a custom design like the second image.
How can i change that background image and all?
my current code is
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
mapView.showsUserLocation = YES;
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *identifier = #"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[_MAPVIEW dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.pinColor = MKPinAnnotationColorPurple;
annotationView.canShowCallout = YES;
}else {
annotationView.annotation = annotation;
}
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButton addTarget:self action:#selector(showDetailView) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = infoButton;
UIImageView *imageV=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"pin.png"]];
annotationView.leftCalloutAccessoryView=imageV;
return annotationView;
}
current annotation detail view design(when i click on pin then i can see the annotation detail view )
but i want something like this design
please help me.

ios: Dont have current location become a pin on map

I have pins that drop on a map and the current location is shown with a blue dot. I added:
- (MKAnnotationView *)mapView:(MKMapView *)amapView viewForAnnotation:(id<MKAnnotation>)annotation{
NSString *identifier =#"mypin";
MKPinAnnotationView *pin = (MKPinAnnotationView *) [amapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(pin ==nil){
pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier] autorelease];
}else{
pin.annotation = annotation;
}
UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
myDetailButton.frame = CGRectMake(0, 0, 23, 23);
myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[myDetailButton addTarget:self action:#selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
pin.rightCalloutAccessoryView = myDetailButton;
pin.enabled = YES;
pin.animatesDrop = TRUE;
pin.canShowCallout = YES;
return pin;
}
But now the current location is a pin instead of the blue dot. How can I stop the annotation for the current location from becoming a pin and keep it as the blue dot.
Any help please?
The "blue dot" is a special annotation, a MKUserLocation. So, in your viewForAnnotation, just add the following two lines at the start to tell iOS to use the standard "blue dot" for the user location annotation:
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
By returning nil, you will tell iOS to use the default "blue dot" annotation for the user location.
For an example of this in practice, see the code sample in Creating Annotation Views from Your Delegate Object section of the Location Awareness Programming Guide.
Simple :
- (MKAnnotationView *)mapView :(MKMapView *)maapView viewForAnnotation:(id <MKAnnotation>) annotation{
#autoreleasepool {
if (annotation == maapView.userLocation)
{
// This code will execute when the current location is called.
return nil;
}
else
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorPurple;
annView.animatesDrop=YES;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
annView.rightCalloutAccessoryView = rightButton;
return annView;
}
}
}
Clean and Swifty (3) way
if annotation is MKUserLocation {
return nil
}

Resources