I want to create a circle overlay over the annotation. I'm using swift 3.0. Any help is appreciated !!
Try a custom overlay. Add this in viewDidLoad:
MKCircle *circle = [MKCircle circleWithCenterCoordinate:userLocation.coordinate radius:1000];
[map addOverlay:circle];
userLocation can be obtained by storing the MKUserLocationAnnotation as a property. Then, to actually draw the circle, put this in the map view's delegate:
- (MKOverlayRenderer *)mapView:(MKMapView *)map viewForOverlay:(id <MKOverlay>)overlay
{
MKCircleRenderer *circleView = [[MKCircleRenderer alloc] initWithOverlay:overlay];
circleView.strokeColor = [UIColor redColor];
circleView.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.4];
return circleView;
}
I tried following code to make circle:
MKCircle *circle = [MKCircle
circleWithCenterCoordinate:userLocation.coordinate radius:1000];
[map addOverlay:circle];
Then in Map View's delegate:
- (MKOverlayView *)mapView:(MKMapView *)map viewForOverlay:(id <MKOverlay>)overlay
{
MKCircleView *circleView = [[MKCircleView alloc] initWithOverlay:overlay];
circleView.strokeColor = [UIColor redColor];
circleView.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.4];
return circleView;
}
It adds a circle around the pin, but how to make the circle stretchable like Reminder App's Location Reminder feature?
Look what I found:
https://github.com/d0ping/DBMapSelectorViewController
You can set up a lot of things like Radius of the circle, Background and Stroke color and even the Radius text.
I create new overlays like this:
MKCircle *circle = [MKCircle circleWithCenterCoordinate:region.coordinate radius:region.radius];
[self.mapView addOverlay:circle];
also I implemented delegate method:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKCircleRenderer *circleRenderer = [[MKCircleRenderer alloc] init];
circleRenderer.fillColor = [UIColor greenColor];
circleRenderer.alpha = 1.f;
return circleRenderer;
}
both parts of code are called, mapView != nil at that moment, it's delegate set,
but I cannot see the circle on my map.
What am I doing wrong?
As per #Rob suggestion you need to init MKCircleRenderer using other method initWithCircle.
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKCircleRenderer *circleRenderer = [[MKCircleRenderer alloc] initWithCircle:overlay];
circleRenderer.fillColor = [UIColor greenColor];
circleRenderer.alpha = 1.f;
return circleRenderer;
}
Also make sure that fence distance is proper enough to visible the circle in map.
For example:
CLLocationDistance fenceDistance = 100000;
MKCircle *circle = [MKCircle circleWithCenterCoordinate:region.coordinate radius:fenceDistance];
[self.mapView addOverlay:circle];
Rather than init, call the MKCircleRenderer method initWithCircle.
Obviously, make sure the delegate of the map view is set, that your code that adds the overlay and that instantiates the renderer is called at all, etc., but initWithCircle is the likely culprit.
I have Map in my app in which is moving as per user location.I have successfully drawn a polyline for source and destination.
Using following code
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay{
MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:overlay];
view1.lineWidth = 27.0;
view1.strokeColor = [UIColor colorWithRed:55.0/255.0 green:168.0/255.0 blue:219.0/255.0 alpha:1];
return view1;
}
But my problem is when map is moving , mean i am changing region of map as user moves , then some times polyline is not shown good some time its show thicker than actual size as you can see in below image.
i am attaching the image below, please let me know what can i do for smooth polyline when map is moving.
EDIT
As Matt suggested i create a subclass of MKPolylineRenderer and implement drawMapRect method as below:
-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
CGMutablePathRef fullPath = CGPathCreateMutable();
BOOL pathIsEmpty = YES;
//merging all the points as entire path
for (int i=0;i< self.polyline.pointCount;i++){
CGPoint point = [self pointForMapPoint:self.polyline.points[i]];
if (pathIsEmpty){
CGPathMoveToPoint(fullPath, nil, point.x, point.y);
pathIsEmpty = NO;
} else {
CGPathAddLineToPoint(fullPath, nil, point.x, point.y);
}
}
//get bounding box out of entire path.
CGRect pointsRect = CGPathGetBoundingBox(fullPath);
CGRect mapRectCG = [self rectForMapRect:mapRect];
//stop any drawing logic, cuz there is no path in current rect.
if (!CGRectIntersectsRect(pointsRect, mapRectCG))return;
UIColor *darker = [UIColor blackColor];
CGFloat baseWidth = 10 / zoomScale;
// draw the dark colour thicker
CGContextAddPath(context, self.path);
CGContextSetStrokeColorWithColor(context, darker.CGColor);
CGContextSetLineWidth(context, baseWidth * 1.5);
CGContextSetLineCap(context, self.lineCap);
CGContextStrokePath(context);
// now draw the stroke color with the regular width
CGContextAddPath(context, self.path);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, baseWidth);
CGContextSetLineCap(context, self.lineCap);
CGContextStrokePath(context);
[super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
}
But Same problem
See below image:
ok, i think i got problem , my polyline is added once, but as user's speed i changing zoom level of MKMapView, zoom level is changed , but polyline width is not refresh,
SO how can i dynamically change lineWidth of mkpolyline ??
The problem is that you are setting your lineWidth at a fixed width (a really big fixed width). This gets larger or smaller as the map is zoomed larger or smaller.
Instead, implement your own MKOverlayRenderer subclass, and override drawMapRect:zoomScale:inContext:. It receives a zoomScale parameter, and so you can adjust the width of your line to look good at what the current scale may be.
Subclass MKPolylineRenderer and override applyStrokePropertiesToContext:atZoomScale: so that it ignores the scale, and draws lines at constant width:
#interface ConstantWidthPolylineRenderer : MKPolylineRenderer
#end
#implementation ConstantWidthPolylineRenderer
- (void)applyStrokePropertiesToContext:(CGContextRef)context
atZoomScale:(MKZoomScale)zoomScale
{
[super applyStrokePropertiesToContext:context atZoomScale:zoomScale];
CGContextSetLineWidth(context, self.lineWidth);
}
#end
Now use it and admire its smooth rendering:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
MKPolyline *polyline = (MKPolyline *)overlay;
ConstantWidthPolylineRenderer *renderer = [[ConstantWidthPolylineRenderer alloc] initWithPolyline:polyline];
renderer.strokeColor = [UIColor redColor];
renderer.lineWidth = 40;
return renderer;
}
You need to use MKPolylineRenderer instead of MKPolylineView
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay {
#try {
MKPolylineRenderer *renderer = [[[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.lineWidth = 27.0;
renderer.strokeColor = [UIColor colorWithRed:55.0/255.0 green:168.0/255.0 blue:219.0/255.0 alpha:1];
return renderer;
}
#catch (NSException *exception) {
NSLog(#"exception :%#",exception.debugDescription);
}
}
Read this one:
The MKPolylineRenderer class provides the visual representation for an MKPolyline overlay object. This renderer strokes the line only; it does not fill it. You can change the color and other drawing attributes of the polygon by modifying the properties inherited from the parent class. You typically use this class as is and do not subclass it.
From Apple library
The MKPolylineView class provides the visual representation for an MKPolyline annotation object. This view strokes the path represented by the annotation. (This class does not fill the area enclosed by the path.) You can change the color and other drawing attributes of the path by modifying the properties inherited from the MKOverlayPathView class. This class is typically used as is and not subclassed.
From Apple library
I have searched far and wide for a proper solution but have yet to find any.
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
MKCircleView* circleView = [[[MKCircleView alloc] initWithOverlay:overlay] autorelease];
circleView.fillColor=[UIColor redColor];
return circleView;
}
-(void)overlay{
MKCircle *circleOverlay;
CLLocationCoordinate2D coords = CLLocationCoordinate2DMake(1.303819,103.7689956); //giza
circleOverlay=[MKCircle circleWithCenterCoordinate:coords radius:200];
[self.mapView addOverlay:circleOverlay];
}
Is there a simple way to add a text into this circle?