comment personnaliser MKPolyLineView pour dessiner des lignes de style différentes

Je veux personnaliser les lignes dessinées sur MKMapView pour montrer un itinéraire afin que les lignes aient une couleur de bordure et une couleur de remplissage. Similaire à ceci où il a une bordure noire et est rempli d'une autre couleur:

ligne bleue avec bordure noire

Je returnne actuellement juste des objects MKPolyLineView de mapView:viewForOverlay: qui fonctionne bien pour les lignes simples. Le docs dit que le MKPolyLineView ne doit pas être sous-classé, alors devrais-je sous-classr MKOverlayView et implémenter mon propre drawMapRect? Ou devrais-je sous-class MKOverlayPathView? Ou créer un rlocation pour MKPolylineView?

EDIT – ce que je request est: où est l'endroit pour mettre votre propre code de dessin de Quartz afin de dessiner vos propres annotations / overlays? Actuellement, j'ai créé une sous-class de MKOverlayView et implémenter mon propre drawMapRect: zoomScale: inContext: Il est assez facile de dessiner la superposition de cette façon, mais est-ce la meilleure solution?

Vous pouvez le faire en implémentant votre propre sous-class MKOverlayPathView, qui dessine le path deux fois dans la carte rect. Une fois plus épais avec du noir et une fois plus mince sur le dessus avec une autre couleur.

J'ai créé un rlocation simple de MKPolylineView qui vous permet de faire cela: ASPolylineView .

Si vous voulez le faire vous-même, les deux principales methods que vous devez implémenter pourraient ressembler à ceci:

 - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { UIColor *darker = [UIColor blackColor]; CGFloat baseWidth = self.lineWidth / 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, self.strokeColor.CGColor); CGContextSetLineWidth(context, baseWidth); CGContextSetLineCap(context, self.lineCap); CGContextStrokePath(context); [super drawMapRect:mapRect zoomScale:zoomScale inContext:context]; } - (void)createPath { // turn the polyline into a path CGMutablePathRef path = CGPathCreateMutable(); BOOL pathIsEmpty = YES; for (int i = 0; i < self.polyline.pointCount; i++) { CGPoint point = [self pointForMapPoint:self.polyline.points[i]]; if (pathIsEmpty) { CGPathMoveToPoint(path, nil, point.x, point.y); pathIsEmpty = NO; } else { CGPathAddLineToPoint(path, nil, point.x, point.y); } } self.path = path; } 

Vous pouvez simplement append deux objects MKPolyLineView avec les mêmes coordonnées, mais avec des épaisseurs différentes.

Ajoutez-en une avec une largeur de ligne de 10 (ou autre) avec strokeColor défini sur noir.

Puis ajoutez-en un autre avec une largeur de ligne de 6 avec strokeColor défini sur votre autre couleur désirée.

Vous pouvez utiliser la même MKPolyLine pour les deux objects MKPolyLineView.

MKPolylineView ne peut être utilisé pour caresser un path désigné. Vous pouvez utiliser certaines des propriétés de MKOverlayPathView pour modifier leur apparence, mais seulement certaines d'entre elles s'appliqueront, par exemple fillColor , strokeColor .

Si vous voulez dessiner quelque chose de plus complexe, vous pouvez utiliser MKOverlayPathView . Il est plus générique et convient donc bien plus que pour les paths caressants. Pour dessiner des lignes simples, le résultat serait identique à MKPolylineView (au less, selon les docs).

Si vous voulez faire un dessin plus complexe, sous-class MKOverlayPathView . Ce que vous essayez de faire est non-sortingvial.

J'utilise une sous-class NamedOverlay qui contient un overlay et un nom:

NamedOverlay.h

 #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface NamedOverlay : NSObject <MKOverlay> @property (strong, readonly, nonatomic) NSSsortingng *name; @property (strong, readonly, nonatomic) id<MKOverlay> overlay; -(id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSSsortingng *)name; @end 

NamedOverlay.m

 #import "NamedOverlay.h" @implementation NamedOverlay - (id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSSsortingng *)name { _name = name; _overlay = overlay; return self; } - (MKMapRect)boundingMapRect { return [_overlay boundingMapRect]; } - (CLLocationCoordinate2D)coordinate { return [_overlay coordinate]; } -(BOOL)intersectsMapRect:(MKMapRect)mapRect { return [_overlay intersectsMapRect:mapRect]; } @end 

et dans le controller de carte, j'instancie deux superpositions avec un nom différent, puis dans MKMapViewDelegate je peux identifier quelle superposition je veux dessiner et faire quelque chose comme:

 - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay { NamedOverlay *namedOverlay = (NamedOverlay *) overlay; MKPolyline *polyline = namedOverlay.overlay; if ([namedOverlay.name isEqualToSsortingng:@"top"]) { MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline]; view1.strokeColor = [UIColor whiteColor]; view1.lineWidth = 25.0; return view1; } else { MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline]; view1.strokeColor = [UIColor blueColor]; view1.lineWidth = 15.0; return view1; } } 

Je sais que cela peut ne pas correspondre à l'approche pure que vous voulez, mais pourquoi ne pas utiliser MKPolygon au lieu d'un MKPolyLine ?
Créez une instance MKPolygon qui représente un type de couloir autour de votre itinéraire , puis, lorsque vous créez le MKPolygonView qui correspond au MKPolygon / corridor que vous avez créé, définissez les propriétés de MKPolygonView pour get une couleur de remplissage et une couleur strokeColor différentes

  myPolygonView.lineWidth=3; myPolygonView.fillColor=[UIColor blueColor]; myPolygonView.strokeColor=[UIColor darkGrayColor]; 

Je n'ai pas essayé moi-même mais cela devrait fonctionner. Le seul inconvénient est que lorsque vous effectuez un zoom avant / arrière, la «largeur» de la «route» va changer ….: /