So I'm really confused. I used:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString* AnnotationIdentifier = #"Annotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView) {
MKPinAnnotationView *customPinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
if (annotation == mapView.userLocation){
customPinView.image = [UIImage imageNamed:#"303761_4417778996801_94858213_n.jpg"];
[customPinView.layer setMasksToBounds:NO];
[self setRoundedView:customPinView toDiameter:kPictureDiameter];
[customPinView.layer setBorderColor:[UIColor whiteColor].CGColor];
[customPinView.layer setBorderWidth:5.0f];
[customPinView.layer setShadowColor:[UIColor blackColor].CGColor];
[customPinView.layer setShadowOpacity:1.0f];
[customPinView.layer setShadowRadius:20.0f];
[customPinView.layer setShadowOffset:CGSizeMake(0, 0)];
[customPinView setBackgroundColor:[UIColor whiteColor]];
}
return customPinView;
} else {
pinView.annotation = annotation;
}
return pinView;
}
to add my own image to the user location pin. And that works. There's two problems though:
Shadows aren't working.
The image I set for the user location pin is off center and looks like this:
user location picture
I've tried fooling around with CGRect, CGPoint, setting the frame, center ect (although I haven't tried changing the bounds as of yet) and nothing changes.
Any help would be so appreciated.
In terms of the image being off center, two thoughts:
I generally use MKAnnotationView when using my own images for annotations, not MKPinAnnotationView. When I tried using MKPinAnnotationView, my images were no longer centered.
If worst comes to worst, you can play with the centerOffset property. I don't think you should need to if you use MKAnnotationView.
Regarding your shadow:
A shadow radius of 20 is so great, that it's so diffuse that you can barely see it. I could barely make it out when I used 20. It was starting to become more visible at 10, and even more so at 5. I don't think this is the real problem here, but as you start to experiment, use a number low enough here so you can clearly see the shadow.
Having said that, I don't think that's the problem. I'm suspicious of the image rounding algorithm. Can you try temporarily commenting that out and see if your shadow appears? But I use shadows on my MKAnnotationView images, and it works fine. Can you share your rounding algorithm with us?
And if that doesn't do it, is this image coinciding with an overlay? (i.e. what's that circle behind the picture). I'd try, again, temporarily removing it and see if that changes the behavior. When I use a MKCircleView, it works fine, but let's make sure we're not doing anything curious there (or with any other drawing routines).
Related
I need to change radius of my MKCircle continuously as user pinches on the screen. As its radius property is read-only, I am removing and recreating the circle and the renderer continuously, which, I believe, causes "flickering" effect when user pinches. It continuously appears/disappears when "animating" which looks really bad visually, creating a crappy UX. Here is my code:
//this method may be called many times a second.
-(void)refreshRadius{ //called when user pinches after updating to correct radius.
if(radiusCircle){
[self.mapView removeOverlay:radiusCircle];
}
radiusCircle = [MKCircle circleWithCenterCoordinate:userCoordinates radius:radius];
[self.mapView addOverlay:radiusCircle level:MKOverlayLevelAboveLabels];
}
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
if(overlay == radiusCircle){
MKCircleRenderer *renderer = [[MKCircleRenderer alloc] initWithCircle:radiusCircle];
renderer.strokeColor = [UIColor colorWithWhite:1 alpha:0.5];
renderer.lineWidth = 0.8;
renderer.fillColor = [UIColor colorWithRed:0.3 green:0.36 blue:0.7 alpha:0.2];
return renderer;
}else{
return nil;
}
}
How can I "animate" the radius smoothly on scale?
After a bit experimenting, I've luckily found a solution. However, while it works perfectly now, it's prone to future internal changes in iOS SDK. I've first set the read-only property "radius" using KVC. Then, I've invalidated my renderer's path, causing it to redraw itself immediately using the new radius. It is not the most-smooth-60FPS-animation-ever but it works really nicely. Here is the code:
[radiusCircle setValue:#(radius) forKey:#"radius"];
[renderer invalidatePath];
radiusCircle is my MKCircle instance, and renderer is my circle renderer. It works.
I have a mapView in my app, and I'm using my own image for the MKAnnotationView, which is the the pin image. Here is my code for setting it.
-(RMAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(RentPin *)annotation{
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[RentPin class]]) {
RMAnnotationView *annotationView = (RMAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(annotationView == nil){
annotationView = [[RMAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = NO;
annotationView.image = [UIImage imageNamed:#"home44.png"];
annotationView.centerOffset = CGPointMake(-10, -10);
}else{
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
It is working fine and the customized image is also showing properly, but when I pinch the mapView for zooming in/out the map, I noticed that the customized image loses its accuracy on the map. Please have a look the images following.
https://www.dropbox.com/s/irrgmohppf08fzr/image1.png
This image shows the pin is at this position, which is quite accurate.
https://www.dropbox.com/s/vvlr4ckk6molqd7/image2.png
After I zoomed out the mapView, the pin crossed the street and showing that this address is in the lake....
(Sorry for the links, since I can't post images because of insufficient reputation.)
Anyone could help me regarding this? my pin image is 44x44 and I also tried setting centerOffset of the pin, it cannot dynamically solved this problem in all the zoom levels.
It's simply the wrong center offset. But be aware that the center offset depends on the type of annotation view you are using. I don't know what RMAnnotationView is. If it's a subclass of MKAnnotationView, the centerOffset should be CGPointMake(0, -imageHeight / 2).
I am making the navigation application by drawing a direction between 2 points. I successfully archive the functionality.
But the direction line is drawn on top of the road label and that label cannot be read as show in the picture below.
this is my code to draw overlay
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
MKPolylineView *overlayView = [[MKPolylineView alloc] initWithPolyline:overlay];
overlayView.lineWidth = 10.0f;
//overlayView.strokeColor = [[UIColor redColor] colorWithAlphaComponent:0.5f];
overlayView.strokeColor = [UIColor redColor];
return overlayView;
}
I can overcome this with a transparent line but it is not the efficient way.
The best way is to draw the line between the map layer and label layer of MKMapView but i don't know how can i archive that.
So any help please.
Thanks.
Assuming you are writing this for iOS maps (not google maps as you tagged the question) and using iOS 7 then when you add the overlay to the map view you have the option of defining which level it is on addOverlay:level:. The levels are defined in the MKMapView class reference
[theMapView addOverlay:theOverlay level:MKOverlayLevelAboveRoads];
I have seen this question posed before and all responses appear largely similar. However, I am simply unable to get any of them to work for my project.
I have an action, updateMap, that is triggered by a button. It shows current location on map (MapKit), and shows some other info relative to their location (geocoding). All of that works fine. What I need to do though is show a radius around their location on the map. Here is what I'm trying that isn't working:
(in updateMap)
//display radius
CLLocationCoordinate2D center = {current.coordinate.latitude, current.coordinate.longitude};
MKCircle *circle = [MKCircle circleWithCenterCoordinate:center radius:1000];
[self.mapView addOverlay:circle];
("current" is a CLLocation var that has the user's current location)
Then, after the action in the implementation file I have this:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
MKCircleView *circleView = [[MKCircleView alloc] initWithOverlay:overlay];
[circleView setFillColor:[UIColor redColor]];
[circleView setStrokeColor:[UIColor blackColor]];
[circleView setAlpha:0.5f];
return circleView;
}
It builds fine, but no circle is ever shown on the map.
Other solutions on this site involved putting the first code shown in the viewDidLoad method, but since the location hasn't been calculated yet (only determined within above-mentioned action) that isn't an option for me.
I appreciate your time and any help you can provide. I'm by no means on the level of many on here so please excuse me if this has an obvious answer. I'm not wanting to be spoon fed, I'm wanting to learn! Thanks for reading.
I using a custom image for my mapkit annotation. But the main problem it seems that I am running into in using a custom image, is that when zoomed out, the annotation is not in the correct point on the map, and ONLY until I zoom in all the way down, will it show the annotation point in the correct place. It seems that when I use a regular pin MKPinAnnotationView, it works normally, as with the pin being in the correct place zoomed in or out, thanks in advance for anyone that can help.
The code I have used is as follows:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"welcome into the map view annotation");
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *pprMapNote = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pprMapNote"];
pprMapNote.image = [UIImage imageNamed:[NSString stringWithFormat:#"GPS_note.png"]];
pprMapNote.canShowCallout = YES;
pprMapNote.centerOffset = CGPointMake(-21,-60);
pprMapNote.calloutOffset = CGPointMake(0, 0);
//[pprMapNote addSubview:pprMapNoteImg];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetail)
forControlEvents:UIControlEventTouchUpInside];
pprMapNote.rightCalloutAccessoryView = rightButton;
//remember to write in conditional for the different icons that should be loaded based on location
UIImageView *pprNoteLocIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"loc_icon_casino.png"]];
pprMapNote.leftCalloutAccessoryView = pprNoteLocIcon;
[pprNoteLocIcon release];
return pprMapNote;
}
You are setting the centerOffset of the annotation view.
Note that this offset is not scaled with the zoom level. The further you zoom out, the further the image will appear from the coordinate.
In the default MKPinAnnotationView, the centerOffset is left at the default of 0,0 and the pin image is designed such that the bottom point of the pin is on the coordinate. So as you zoom further out, the pin image seems to grow relative to the map under it but the bottom of the pin is still pointing to the coordinate.
You need to either adjust the centerOffset based on your image or modify your image so you don't need to set centerOffset. Or just try commenting out the setting of centerOffset--maybe you don't need it.
Some other unrelated items:
You have a memory leak for the pprMapNote alloc+init (add an autorelease)
You should be using dequeueReusableAnnotationViewWithIdentifier to allow for annotation view re-use.
Instead of using addTarget to call your own method for the callout button press, it's much better to use the map view's own delegate method calloutAccessoryControlTapped
See this answer for an example of the above three points.
The Pin is drawn in a separate view, so it will not zoom based on the status of your view.
You have to set the size of your custom Pin image manually. This can easily be done using the centerOffset. For most cases it is enough to set the height of the frame to half the size of the image. The image is fully filled in the frame, so you can easily use this frame size(height).
aView.image = [UIImage imageNamed ... ];
aView.centerOffset = CGPointMake(0,-aView.frame.size.height*0.5);