2017-03-06 85 views
14

我已经通过以下代码创建了像CAShapeLayer这样的动画折线,我已经将CAShapeLayer作为子图层添加到GMSMapiew中,但是,如果我移动地图,图层将不会移动。在哪里添加图层,以便它与地图一起移动?如何在GMSMapView中获取动画折线路线,以便在地图移动时与地图一起移动?

func layer(from path: GMSPath) -> CAShapeLayer { 
     let breizerPath = UIBezierPath() 
     let firstCoordinate: CLLocationCoordinate2D = path.coordinate(at: 0) 
     breizerPath.move(to: self.mapView.projection.point(for: firstCoordinate)) 
     for i in 1 ..< Int((path.count())){ 
      print(path.coordinate(at: UInt(i))) 
      let coordinate: CLLocationCoordinate2D = path.coordinate(at: UInt(i)) 
      breizerPath.addLine(to: self.mapView.projection.point(for: coordinate)) 
     } 

     let shapeLayer = CAShapeLayer() 
     shapeLayer.path = breizerPath.reversing().cgPath 
     shapeLayer.strokeColor = UIColor.green.cgColor 
     shapeLayer.lineWidth = 4.0 
     shapeLayer.fillColor = UIColor.clear.cgColor 
     shapeLayer.lineJoin = kCALineJoinRound 
     shapeLayer.lineCap = kCALineCapRound 
     shapeLayer.cornerRadius = 5 
     return shapeLayer 
    } 

    func animatePath(_ layer: CAShapeLayer) { 
     let pathAnimation = CABasicAnimation(keyPath: "strokeEnd") 
     pathAnimation.duration = 6 
     //pathAnimation.delegate = self 
     pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 
     pathAnimation.fromValue = Int(0.0) 
     pathAnimation.toValue = Int(1.0) 
     pathAnimation.repeatCount = 100 
     layer.add(pathAnimation, forKey: "strokeEnd") 
    } 

加进GoogleMapView由

let shapelayer: CAShapeLayer = self.layer(from: path!) 
    self.animatePath(shapelayer) 
    self.mapView.layer.addSublayer(shapelayer) 

I get the following output

+0

尝试将此行添加为'UIViewController's'视图子视图,而不是'GMSMapView' – JuicyFruit

回答

14

我创建GMSPath动画与路径coordinate

enter image description here

目标C

接口

@interface MapWithTracking() 

@property (weak, nonatomic) IBOutlet GMSMapView *mapView; 

@property (nonatomic,strong) GMSMutablePath *path2; 

@property (nonatomic,strong)NSMutableArray *arrayPolylineGreen; 

@property (nonatomic,strong) GMSPolyline *polylineBlue; 

@property (nonatomic,strong) GMSPolyline *polylineGreen; 

@end 

实施通货膨胀

-(void)viewDidLoad { 
    _arrayPolylineGreen = [[NSMutableArray alloc] init]; 
    _path2 = [[GMSMutablePath alloc]init]; 
} 

得到一个GMSPath并创建一个蓝色折线。

-(void)createBluePolyline(GMSPath *path) { 

     // Here create a blue poly line 
     _polylineBlue = [GMSPolyline polylineWithPath:path]; 
     _polylineBlue.strokeColor = [UIColor blueColor]; 
     _polylineBlue.strokeWidth = 3; 
     _polylineBlue.map = _mapView; 

     // animate green path with timer 
     [NSTimer scheduledTimerWithTimeInterval:0.003 repeats:true block:^(NSTimer * _Nonnull timer) { 
      [self animate:path]; 
     }]; 

} 

动画绿色折线

添加坐标路径2,并把映射

-(void)animate:(GMSPath *)path { 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (i < path.count) { 
      [_path2 addCoordinate:[path coordinateAtIndex:i]]; 
      _polylineGreen = [GMSPolyline polylineWithPath:_path2]; 
      _polylineGreen.strokeColor = [UIColor greenColor]; 
      _polylineGreen.strokeWidth = 3; 
      _polylineGreen.map = _mapView; 
      [arrayPolylineGreen addObject:_polylineGreen]; 
      i++; 
     } 
     else { 
      i = 0; 
      _path2 = [[GMSMutablePath alloc] init]; 

      for (GMSPolyline *line in arrayPolylineGreen) { 
       line.map = nil; 
      } 

     } 
    }); 
} 
+0

我检查了你的代码,它很容易阅读。但我有一个问题,Polyline总是会在3毫秒后绘制?我的意思是如果经度和纬度是复杂的结构,那么绘制路径需要时间。 (取决于主线负载) –

+0

您可以根据您的要求设置第二个。如果路径结构更加复杂,那么它就像魅力一样,因为在主线程中我们不会进行复杂的操作。你也可以做后台线程,但动画不像魅力那样工作。 –

+0

是的问题是,如果我使用3毫秒的动画,那么在所有设备中并不总是相同的动画。我已经使用DispatchQueue进行此操作。这很好,或者我需要使用nsTimer?你能请教我吗? –

1

移动的层每当地图通过实现委托mapView:didChangeCameraPosition:移动。

+0

我已经从GMSPath坐标创建了breizerpath路径并从breizerpath创建了CAShapeLayer。如何将图层框架更改为cameraPosition? @Jon – Elangovan

+0

您可以将坐标转换为点以及使用GMSMapView上的投影属性进行坐标转换。请参阅https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_projection –

0

您需要为此使用GMSPolyline。创建一个GMSPolyline实例,将您的GMSMapView实例设置为它的父映射。

GMSPolyline* routeOverlay = // config 
routeOverlay.map = // my GMSMapView instance 

就这样。你不需要做任何额外的事情来使它随着地图相机的移动而移动。它会自动完成。

+0

该问题要求提供一种方法来创建该路径,我认为您不能使用GMSPolyline –

+0

@JonRose您可以使用GMSPath实例创建一个GMSPolyline实例。您可以使用从Google Places API收到的encodedPath字符串创建GMSPath,以查找两个位置之间的路线。我认为Elangovan已经在使用这个设置。 –

+0

您可以为该路径制作动画吗? –

12

SWIFT

Declartion

var polyline = GMSPolyline() 
var animationPolyline = GMSPolyline() 
var path = GMSPath() 
var animationPath = GMSMutablePath() 
var i: UInt = 0 
var timer: Timer! 

要Darw路线

func drawRoute(routeDict: Dictionary<String, Any>) { 

     let routesArray = routeDict ["routes"] as! NSArray 

     if (routesArray.count > 0) 
     { 
      let routeDict = routesArray[0] as! Dictionary<String, Any> 
      let routeOverviewPolyline = routeDict["overview_polyline"] as! Dictionary<String, Any> 
      let points = routeOverviewPolyline["points"] 
      self.path = GMSPath.init(fromEncodedPath: points as! String)! 

      self.polyline.path = path 
      self.polyline.strokeColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5) 
      self.polyline.strokeWidth = 3.0 
      self.polyline.map = self.mapView 

      self.timer = Timer.scheduledTimer(timeInterval: 0.003, target: self, selector: #selector(animatePolylinePath), userInfo: nil, repeats: true) 
     } 
    } 

动画路径

func animatePolylinePath() { 
     if (self.i < self.path.count()) { 
      self.animationPath.add(self.path.coordinate(at: self.i)) 
      self.animationPolyline.path = self.animationPath 
      self.animationPolyline.strokeColor = UIColor.black 
      self.animationPolyline.strokeWidth = 3 
      self.animationPolyline.map = self.mapView 
      self.i += 1 
     } 
     else { 
      self.i = 0 
      self.animationPath = GMSMutablePath() 
      self.animationPolyline.map = nil 
     } 
    } 

不要忘记在viewWillDisappear

停止计时器
self.timer.invalidate() 

输出

enter image description here

+0

Tx在快速转换 –

+0

为快速转换而感谢! – Bishan

+0

你好在操作系统版本10.3.1(iphone 5)它不工作完美。有时会变得很慢并且在设备中快速运行。在iphone 6中,它在OS 10.3.1中变慢,而在OS 10.0中则变慢。 – Nisha