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.
Related
I am trying to create custom annotation as each annotation save some data which i need to show on tap of pin. But i need to show default ios pin image. Everything is working fine but pin will only show when i set any image. without setting image it is not showing default ios pin. My code is
CustomAnnotation.h file
#interface CustomAnnotation : NSObject<MKAnnotation>
#property(nonatomic,strong)NSString *title;
#property(nonatomic,strong)NSString *subTitle;
#property(nonatomic)CLLocationCoordinate2D coordinate;
#property(nonatomic,strong) UserDevice *userData;
-(instancetype)initWithUserData:(UserDevice *)userData;
on mapViewC.h
-(void)addMarkersOnMap{
for (UserDevice* userDevice in markersArray) {
CustomAnnotation *point = [[CustomAnnotation alloc]initWithUserData:userDevice];
point.coordinate = CLLocationCoordinate2DMake(userDevice.latitude, userDevice.longitude);
point.userData = userDevice;
point.title = #"dszf";
[mapview addAnnotation:point];
MKMapRect mapRect = [self getZoomingRectOnMap:mapview toFitAllOverlays:YES andAnnotations:YES includeUserLocation:NO];
[mapview setVisibleMapRect:mapRect edgePadding:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0) animated:YES];
}
}
#pragma mark - MKMapView Delegate methods
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *customAnnotation = annotation;
MKAnnotationView *customAnnotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"annotationViewID"];
if (customAnnotationView == nil){
customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotationViewID"];
}
// customAnnotationView.image = [UIImage imageNamed:#"pin-1"];
customAnnotationView.canShowCallout = true;
customAnnotationView.annotation = customAnnotation;
return customAnnotationView;
}
return nil;
}
Instead of CustomAnnotationView use MKPinAnnotationView in your viewForAnnotation MKMapViewDelegate method
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *customAnnotation = annotation;
MKPinAnnotationView *customAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"annotationViewID"];
if (customAnnotationView == nil){
customAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotationViewID"];
}
// customAnnotationView.image = [UIImage imageNamed:#"pin-1"];
customAnnotationView.canShowCallout = true;
customAnnotationView.annotation = customAnnotation;
return customAnnotationView;
}
return nil;
}
Hope this helps
CustomAnnotation *customAnnotation = annotation;
NSString *annotationIdentifier = #"PinViewAnnotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier: annotationIdentifier];
if (pinView ==nil) {
pinView = [[MKPinAnnotationView alloc]initWithAnnotation: customAnnotation reuseIdentifier: annotationIdentifier];
}
pinView.pinColor = MKPinAnnotationColorGreen; // change color
pinView.canShowCallout = YES;
pinView.enabled = YES;
mapView selectAnnotation:pinView animated:YES];
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 have built a Map application that uses the Kingpin map pin clustering library, (found here) at present the library succeeds in approximating the position of the pins and placing the cluster pin. However, the original pins are never removed as seen here. I think the relevant code is this:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
MKAnnotationView *annotationView = nil;
if([annotation isKindOfClass:[KPAnnotation class]]){
KPAnnotation *kingpinAnnotation = (KPAnnotation *)annotation;
if ([kingpinAnnotation isCluster]) {
annotationView=(MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"cluster"];
if (annotationView==nil){
annotationView=[[MKAnnotationView alloc]initWithAnnotation:kingpinAnnotation reuseIdentifier:#"cluster"];
annotationView.canShowCallout=YES;
annotationView.image=[UIImage imageNamed:#"icon_notif_recall.png"];
annotationView.frame=CGRectMake(0,0,25,25);
}
}else{
annotationView=(MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if (annotationView==nil){
annotationView=[[MKAnnotationView alloc]initWithAnnotation:[kingpinAnnotation.annotations anyObject]reuseIdentifier:#"pin"];
annotationView.canShowCallout=YES;
annotationView.image=[UIImage imageNamed:#"icon_notif_recall.png"];
annotationView.frame=CGRectMake(0,0,25,25);
}
}
return annotationView;
}else if([annotation isKindOfClass:[REC_CustomAnnotation class]]){//Check that is our custom pin class
REC_CustomAnnotation *myLocation = (REC_CustomAnnotation *)annotation;
MKAnnotationView *annotationView=[mapView dequeueReusableAnnotationViewWithIdentifier:#"REC_CustomAnnotation"];
if(annotationView==nil){
annotationView=myLocation.annotationView;
}else{
annotationView.annotation=annotation;
}
return annotationView;
}else{
return annotationView;
}
}
but I am really not sure what is wrong. Any thoughts on what the problem is or things to try would be greatly appreciated.
As it turned out, the function posted above was in fact the problem. However, I was on the complete wrong track in terms of understanding how kingpin worked. Got everything working with this:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
MKAnnotationView *annotationView = nil;
if ([annotation isKindOfClass:[KPAnnotation class]]) {
KPAnnotation *a = (KPAnnotation *)annotation;
if ([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
if (a.isCluster) {
annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"cluster"];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:a reuseIdentifier:#"cluster"];
}
annotationView.image=[UIImage imageNamed:#"icon_notif_recall.png"];
annotationView.frame=CGRectMake(0,0,25,25);
}else {
annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:[a.annotations anyObject] reuseIdentifier:#"pin"];
}
KPAnnotation *thisKPAnnot=(KPAnnotation *)annotation;
NSMutableArray *arrayOfAnnots = [NSMutableArray arrayWithArray:[[thisKPAnnot annotations] allObjects]];
if([arrayOfAnnots count]==1){
REC_CustomAnnotation *thisAnnot=(REC_CustomAnnotation *)[arrayOfAnnots objectAtIndex:0];
if(thisAnnot.type==1){
annotationView.image=[UIImage imageNamed:#"icon_notif_facebook.png"];
}else if(thisAnnot.type==2){
annotationView.image=[UIImage imageNamed:#"icon_notif_twitter.png"];
}else if(thisAnnot.type==3){
annotationView.image=[UIImage imageNamed:#"icon_notif_instagram.png"];
}else if(thisAnnot.type==4){
annotationView.image=[UIImage imageNamed:#"icon_notif_foursquare.png"];
}else if(thisAnnot.type==5){
annotationView.image=[UIImage imageNamed:#"icon_notif_camera.png"];
}else{
annotationView.image=[UIImage imageNamed:#"icon_notif_recall.png"];
}
}else{annotationView.image=[UIImage imageNamed:#"icon_notif_recall.png"];}
annotationView.frame=CGRectMake(0,0,25,25);
}
annotationView.canShowCallout = YES;
}
return annotationView;
}
I hope this ends up helping someone in the future.
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.
I have a set of annotations that are supposed to take you to a new view and display parse information on it. I do not believe that the new view is grabbing the objectId of each geopoint though because the label is not working.
Here is my code:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation {
// Let the system handle user location annotations.
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString *pinIdentifier = #"CustomPinAnnotation";
// Handle any custom annotations.
if ([annotation isKindOfClass:[PAWPost class]])
{
// Try to dequeue an existing pin view first.
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[aMapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];
if (!pinView)
{
// If an existing pin view was not available, create one.
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:pinIdentifier];
}
else {
pinView.annotation = annotation;
}
static NSString* BridgeAnnotationIdentifier = #"bridgeAnnotationIdentifier";
MKPinAnnotationView *customPinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier];
pinView.pinColor = MKPinAnnotationColorPurple;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return pinView;
}
return nil;
}
And here is the push to the new View.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
DetailViewController *objDetail = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
objDetail.pawpost = (PAWPost *)view.annotation;
[self.navigationController pushViewController:objDetail animated:YES];
}
And here is the Code on the new View page.
[super viewDidLoad];
PFObject *gameScore = [PFObject objectWithClassName:#"Arcade"];
self.title = #"Detail View";
PFQuery *query = [PFQuery queryWithClassName:#"Arcade"];
NSString *objectId = gameScore.objectId;
[query getObjectInBackgroundWithId:ObjectIdentifier block:^(PFObject *gameScore, NSError *error) {
lblTitle.text = gameScore[#"name"];
NSLog(#"%#", gameScore);
}];