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.
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 am trying to add a circular region on my MKMapView like the picture below for my current location. I can pin the map with annotations but don't know how to get it to show a circular region like this with a radius and have it shaded.
So I figured it out...
Below is how I did it along with code.
Step 1: - Create MKCircle
MKCircle *circleOverlay = [MKCircle circleWithCenterCoordinate:zoomLocation radius:300];//radius in meters
Step 2: - Set title and add to Map Overlays
[circleOverlay setTitle:#"Circle1"];
[_mapView addOverlay:circleOverlay];
Step 3: - Implement the mapView:rendererForOverlay: method in my MapViewDelegate
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
if ([overlay isKindOfClass:[MKCircle class]])
{
MKCircleRenderer* aRenderer = [[MKCircleRenderer alloc] initWithCircle:(MKCircle *)overlay];
aRenderer.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
aRenderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
aRenderer.lineWidth = 3;
return aRenderer;
}else{
return nil;
}
}
That was it! Boom! Hope it helps someone in the future! Not sure if this is the best way but it achieve my goal!
Edit: make sure to set your mapView's delegate to self or the required delegate method will not be called.
I am drawing x amount of lines on an MKMapView. The data is being downloaded from a webservice and for each line that needs drawing I am creating a MKPolyline, adding it to an overlayArray (some overlays have more than one polyline) and finally adding that overlay to the map via:
[self.mapView addOverlays:overlayArray];`
The next function is therefore called which works wonderfully:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if (![overlay isKindOfClass:[MKPolygon class]]) {
MKPolyline *route = overlay;
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
renderer.strokeColor = [lineColours objectForKey:route.title];
renderer.lineWidth = 3.0;
return renderer;
} else {
return nil;
}
}
As you can see, the strokeColor gets the correct UIColor from a pre-defined NSMutableDictionary. This all works as expected.
However, some of the lines overlap and using a single colour is not always desired. I was wondering if there was a way of creating a line made up of two or even 3 colours, but not a gradient along the line as seen in many fitness apps, but colours across the line. For example, another use would be to draw a motorway route made up of two white lines with a transparent strip in the middle.
This is quite important for an app I am developing so I will post any findings I find here, and I hope that other people can share their thoughts and knowledge too.
I have an array of coordinates and I already know how to add it on a map as annotations.
What I'd like to do now is the following:
each annotation should be a red circle (no pins) that represents a fixed radius of 1 Km around the coordinates. That means that if I zoom in or out the map, the circle should adjusts itself to always represent a 1 Km radius;
if two or more circles overlaps, their color intensity should increase. For example, three or four overlapping circles will produce a solid red circle.
That's all. I have no idea where to start with this, so any help will be greatly appreciated.
For starter you can use below code but you will have to tweak it little to make it of your use:
in .h file confirm to MKMapViewDelegate
#interface MapViewController : UIViewController <MKMapViewDelegate>
Then,
in "viewDidLoad"
CLLocationCoordinate2D center = {X cordinate, Y cordinate};
//--> Add overlay
MKCircle *mCircle = [MKCircle circleWithCenterCoordinate:center radius:1000]; //set radius as per your need
[self.mapView addOverlay:mCircle];
Then,
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
MKCircleView *cirView = [[MKCircleView alloc] initWithOverlay:overlay];
[cirView setFillColor:[UIColor redColor]];
[cirView setStrokeColor:[UIColor blackColor]];
[cirView setAlpha:0.3f];
return cirView;
}
I think this should get you started.
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];