Gradient along MKPolyLineView ( MKPolylineRenderer )
So the original answer is here https://stackoverflow.com/a/20159374/2606068
you can find the demo here https://github.com/wdanxna/GradientPolyline
and some improvement tips provided by @Templar is:
- prepare the path directly in the init.
- check also for CGRectContains, not only for intersection.
thanks man! :p
Polyline won't show up in MapKit
First you need to add this line, I think you already have added but anyway
self.mapView.delegate = self
After that you need to implement this MKMapViewDelegate
method func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
and return the MKOverlayRenderer
needed for your current overlay in this case MKPolylineRenderer
this is an important part if you don't implement this method then you never will have your polyline rendered
implementation will be something like this
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let overlayGeodesic = overlay as? MKGeodesicPolyline
{
let overLayRenderer = MKPolylineRenderer(polyline: overlayGeodesic)
overLayRenderer.lineWidth = 5
overLayRenderer.strokeColor = UIColor.blue
return overLayRenderer
}
if let overlayTile = overlay as? MKTileOverlay{
let overLayRenderer = MKTileOverlayRenderer(tileOverlay: overlayTile)
return overLayRenderer
}
return MKOverlayRenderer(overlay: overlay)
}
And voila! there is your polyLine rendered
MKPolyline / MKPolylineRenderer changing color without remove it
Complex animations or shading/gradients will probably require creating a custom overlay renderer class.
These other answers give ideas about how to draw gradient polylines and animations will most like require a custom overlay renderer as well:
- how to customize MKPolyLineView to draw different style lines
- Gradient Polyline with MapKit ios
- Draw CAGradient within MKPolyLineView
Apple's Breadcrumb sample app also has an example of a custom renderer which you may find useful.
However, if you just want to update the line's color (say from blue to red), then you may be able to do that as follows:
- Get a reference to the
MKPolyline
you want to change. - Get a reference to the
MKPolylineRenderer
for the polyline obtained in step 1. This can be done by calling the map view'srendererForOverlay:
instance method (not the same as themapView:rendererForOverlay:
delegate method. - Update the renderer's
strokeColor
. - Call
invalidatePath
on the renderer.
Not sure what you want but you may be able to "animate" the color going from blue to red by changing the color and calling invalidatePath gradually in timed steps.
Another important thing is to make sure the rendererForOverlay
delegate method also uses the line's "current" color in case the map view calls the delegate method after you've changed the renderer's strokeColor
directly.
Otherwise, after panning or zooming the map, the polyline's color will change back to whatever's set in the delegate method.
You could keep the line's current color in a class-level variable and use that in both the delegate method and the place where you want to change the line's color.
An alternative to a class-level variable (and probably better) is to either use the MKPolyline's title
property to hold its color or a custom polyline overlay class (not renderer) with a color property.
Example:
@property (nonatomic, strong) UIColor *lineColor;
//If you need to keep track of multiple overlays,
//try using a NSMutableDictionary where the keys are the
//overlay titles and the value is the UIColor.
-(void)methodWhereYouOriginallyCreateAndAddTheOverlay
{
self.lineColor = [UIColor blueColor]; //line starts as blue
MKPolyline *pl = [MKPolyline polylineWithCoordinates:coordinates count:count];
pl.title = @"test";
[mapView addOverlay:pl];
}
-(void)methodWhereYouWantToChangeLineColor
{
self.lineColor = theNewColor;
//Get reference to MKPolyline (example assumes you have ONE overlay)...
MKPolyline *pl = [mapView.overlays objectAtIndex:0];
//Get reference to polyline's renderer...
MKPolylineRenderer *pr = (MKPolylineRenderer *)[mapView rendererForOverlay:pl];
pr.strokeColor = self.lineColor;
[pr invalidatePath];
}
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineRenderer *pr = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
pr.strokeColor = self.lineColor;
pr.lineWidth = 5;
return pr;
}
return nil;
}
Polyline not showing in MapKit [Xcode 9.0 - Swift 4.0]
It's probably just a typo. Replace
func mapView(_mapView: MKMapView, rendererFor overlay: MKOverlay)-> MKOverlayRenderer{
with
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
Related Topics
iPhone - Draw Transparent Rectangle on Uiview to Reveal View Beneath
How to Send Data Back by Popviewcontrolleranimated for Swift
Avcapturesession with Multiple Previews
Setting Selected Image in Tab Bar Controller with Storyboard
Levenshtein Distance Algorithm Better Than O(N*M)
Class Has No Initializers Swift
iOS How to Detect When App Was Removed from Process
Xcode 8 :Function Types Cannot Have Argument Label Breaking My Build
Ios9 - This Application Is Modifying the Autolayout Engine from a Background Thread -- Where
How to Change My iOS Applications' Entitlements
Module Compiled with Swift 4.0 Cannot Be Imported in Swift 4.0.1
iOS 8 Swift - Tableview with Embedded Collectionview
How to Load an Uiimage into a Swiftui Image Asynchronously
How to Make a Button Continually Call a Function When Held Down (Spritekit)
Can't Assign Multiple Buttons to Uinavigationitem When Using Storyboard with iOS 5
Dealing with iPad Mini Screen Size
Nsurlconnection Get Request Returns -1005, "The Network Connection Was Lost"