2017-01-22 62 views
1

我正在尋找更改用戶位置註釋的外觀。我明白現在可以使用MGLUserLocationAnnotationView,但是,我不確定如何實現這一點。任何人都可以提供一個簡單的例子來說明這是如何完成的Swift 3 - Mapbox - 自定義用戶位置註釋

謝謝

+0

確實[這個問題](http://stackoverflow.com/q/40279217/1072229)幫幫我? –

+0

我在尋找更具體的例子。 – JordanW

+0

這個答案沒有鏈接到一個例子,'MGLFaux3DUserLocationAnnotationView'。那裏的'.h'和'.m'文件似乎是一個完整的實現。 –

回答

7

你說得對。 MapBox API MGLUserLocationAnnotationView描述非常短。用戶位置視圖自定義從MapBox iOS SDK 3.4.0開始可用。 See also the feature comments on the MapBox GitHub

重要的是要注意:MGLUserLocationAnnotationView是MGLAnnotationView的子類。這意味着MGLUserLocationAnnotationView的行爲就像普通的註釋視圖。

以下是如何自定義用戶位置視圖的示例。創建一個新類(例如CustomUserLocationAnnotationView)並覆蓋layoutSubviews()以添加自定義代碼。在這個例子中,我使用UIImage UserLocationIcon.png可視化地圖上的用戶位置。

import Foundation 
import UIKit 
import Mapbox 

final class CustomUserLocationAnnotationView: MGLUserLocationAnnotationView { 
    override init(reuseIdentifier: String?) { 
     super.init(reuseIdentifier: reuseIdentifier) 
    } 

    override init(frame: CGRect) { 
     super.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     // Force the annotation view to maintain a constant size when the map is tilted. 
     scalesWithViewingDistance = false 

     layer.contentsScale = UIScreen.main.scale 
     layer.contentsGravity = kCAGravityCenter 

     // Use your image here 
     layer.contents = UIImage(named: "UserLocationIcon")?.cgImage 
    } 
} 

在UIViewController或任何其他(如服務類)與至少兩種功能-mapViewDidFinishLoadingMap實現MGLMapViewDelegate: 和-mapView:viewForAnnotation :.見我的評論在線:

extension ViewController: MGLMapViewDelegate { 
    // Wait until the map is loaded before proceed with other actions on map 
    func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) { 
     // Show the user location here 
     mapView.showsUserLocation = true 
    } 

    func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? { 
     // Customise the user location annotation view 
     if annotation is MGLUserLocation { 
      var userLocationAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "CustomUserLocationAnnotationViewIdentifier") as? CustomUserLocationAnnotationView 

      if userLocationAnnotationView == nil { 
       userLocationAnnotationView = CustomUserLocationAnnotationView(reuseIdentifier: "CustomUserLocationAnnotationViewIdentifier") 
      } 

      // Optional: You can save the annotation object for later use in your app 
      self.userLocationAnnotation = annotation 

      return userLocationAnnotationView 
     } 

     // Customise your annotation view here... 

     return customAnnotationView 
    } 
} 

的MapView -mapView:viewForAnnotation:委託函數被調用,包括用戶註釋視圖中的每個註釋視圖實例。

可選:爲了讓您的CustomUserLocationAnnotationView例如,你可以在你的代碼的任何地方使用這個函數:

// The userLocationAnnotation was previously saved in your ViewController in the -mapView:viewForAnnotation: delegate function 
    let view = mapView.view(for: self.userLocationAnnotation) as? CustomUserLocationAnnotationView 
+0

這很奇怪,當我開始用戶跟蹤時,我的註釋視圖不會被調用。 – huggie

+0

@huggie我也有同樣的問題,'viewForAnnotation'沒有被調用。我發現這是因爲我在storyboard中設置了'mapView',並且在那裏我設置了'ShowUserLocation'爲'On'。將它設置爲'Default'後,我的'viewForAnnotation'被調用。在代碼中使用'mapView.showsUserLocation'確定。 – Andrej

+0

@Andrej謝謝你解決了我的問題!另外,我必須調用'CustomUserLocationAnnotationView'上的'setNeedLayout()'來調用'layoutSubviews()'。 – huggie