2017-03-06 83 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