在swift

时间:2015-05-22 04:20:54

标签: ios swift annotations mapkit coordinates

我想每60秒更新一次地图视图&使用自定义图钉/图像制作注释,但希望将标准图钉[红色 - 请参见Figure 6-1]图标显示为先前绘制的注释。我尝试下面的代码,但这不能正常工作。使用另一个自定义图像可以工作但我无法显示默认/标准红色图钉到之前的注释。请参阅" currentLocationHasBeenUpdated"功能,我试图在上一个注释中显示标准的红色图标。请让我知道如何实现这一目标。感谢。

我的ViewController:

   import UIKit
    import MapKit

    class FirstTabController: UIViewController, MKMapViewDelegate, DelegateForUpdateCurrentLocation {
        @IBOutlet weak var mapView: MKMapView!
        var gpsLocations : [[String: AnyObject]]!
        var dataManager : DataManager!
        var currentAnnotation : MKAnnotation!

        //Return CLLocation Coordinate
        func getLocationObject(latitude:Double, longitude:Double) -> CLLocationCoordinate2D {
            return CLLocationCoordinate2D(
                latitude: latitude,
                longitude: longitude
            )
        }

        //Create annotation object & return
        func createAnnotation(latitude:Double, longitude:Double, locationName:String, territory:String) -> MKPointAnnotation {
            let annotation = MKPointAnnotation()
            annotation.coordinate = self.getLocationObject(latitude, longitude: longitude)
            annotation.title = locationName
            annotation.subtitle = territory
            return annotation
        }

        //Create annotaion for current ship position
        func createAnnotationForCurrentPosition(location:[String: AnyObject]) -> MKPointAnnotation {
            let latitude = (location["latitude"] as? Double)!
            let longitude = (location["longitude"] as? Double)!
            let name = (location["locationName"] as? String)!
            let territory = (location["territory"] as? String)!

            return self.createAnnotation(latitude, longitude: longitude, locationName: name, territory: territory)
        }

        //Set region on map view
        func setRegion(location:[String: AnyObject]){
            let latitude = (location["latitude"] as? Double)!
            let longitude = (location["longitude"] as? Double)!
            let location = self.getLocationObject(latitude, longitude: longitude)

            //Set zoom span
            let span = MKCoordinateSpanMake(0.05, 0.05)

            //Create region on map view & show
            let region = MKCoordinateRegion(center: location, span: span)
            self.mapView.setRegion(region, animated: true)
        }

        //This function will fire from data manager when current location from API has been updated
        func currentLocationHasBeenUpdated(location:[String: AnyObject]){
            dispatch_async(dispatch_get_main_queue()){
                if self.currentAnnotation != nil {
                    var currentAnnotationView = self.mapView.viewForAnnotation(self.currentAnnotation)
                    if currentAnnotationView != nil {
                        currentAnnotationView.image = nil //this line makes app crash [gave nil to show standard red icon]
                        // currentAnnotationView.image = UIImage(named:"first") - this line works perfectly with different icon. but i don't want any custom icon except the standard red one
                    }
                }
                self.mapView.addAnnotation(self.createAnnotationForCurrentPosition(location))
                self.setRegion(location)
            }
        }

        //Update map view by scheduling time if current location is changed yet
        func updateMapView() {
            self.dataManager.getCurrentLocation()
        }

        override func viewDidLoad() {
            super.viewDidLoad()

            //Get gps locations from data manager
            self.dataManager = DataManager()
            self.dataManager.delegate2 = self
            self.dataManager.getCurrentLocation()
            //self.mapView.userTrackingMode = MKUserTrackingMode.FollowWithHeading

            //Get GPS location by scheduling time
            NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("updateMapView"), userInfo: nil, repeats: true)
        }

        func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer!{
            if overlay is MKPolyline {
                var polylineRenderer = MKPolylineRenderer(overlay: overlay)
                polylineRenderer.strokeColor = UIColor.blueColor()
                polylineRenderer.lineWidth = 2
                return polylineRenderer
            }

            return nil
        }

        //Make custom annotaion pin if the annotation is of ship's current position
        func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView!{
            println("Hello")
            self.currentAnnotation = annotation

            //Custom annotation view with custom pin icon
            let reuseId = "custom"
            var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)

            if annotationView == nil {
                annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
                annotationView.canShowCallout = true
            }
            else {
                annotationView.annotation = annotation
            }

            //Set annotation specific properties after the view is dequeued or created...
            annotationView.image = UIImage(named:"pinicon")

            return annotationView
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }

和来自api的坐标

import Foundation

extension String {
    func toDouble() -> Double? {
        return NSNumberFormatter().numberFromString(self)?.doubleValue
    }
}

class DataSet{
    var settings : Settings!
    var getService : GetService!
    var currentLocation : [String: AnyObject]!

    //Object initialization for API call
    init(){
        self.settings = Settings()
        self.getService = GetService()
    }

    func getCurrentLocation(callback:([String: AnyObject]) -> ()){
        self.getService.apiCallToGet(self.settings.getCoordinates(), callback: {
            (response) in
            var location = [String: AnyObject]()

            for item in response {
                if let dictionary = item as? NSDictionary {

                    if let lat = dictionary["Lat"] as? String {
                        if lat.toDouble() != nil {
                            location["latitude"] = lat.toDouble()!
                        }
                    }

                    if let long = dictionary["Long"] as? String {
                        if long.toDouble() != nil {
                            location["longitude"] = long.toDouble()!
                        }
                    }

                    if let name = dictionary["Name"] as? String {
                        location["locationName"] = name
                    }

                    if let territory = dictionary["Territory"] as? String {
                        location["territory"] = territory
                    }

                    println(location["latitude"]!)
                    println(location["longitude"]!)

                    if self.currentLocation != nil {
                        if ((self.currentLocation["latitude"] as? Double) != (location["latitude"] as? Double)) && ((self.currentLocation["longitude"] as? Double) != (location["longitude"] as? Double)){
                            self.currentLocation = location
                            callback(location)
                        }
                    } else {
                        self.currentLocation = location
                        callback(location)
                    }
                }
            }
        })
    }
}

1 个答案:

答案 0 :(得分:0)

我通过创建下面的自定义注释类来解决我的问题 -

import UIKit
import MapKit

var ARROW_ANNOTATION : NSString = "ARROW_ANNOTATION"
var PIN_ANNOTATION  : NSString = "PIN_ANNOTATION"

class Annotation: NSObject, MKAnnotation {
    var currentLocation: CLLocationCoordinate2D
    var _title : String
    var subTitle : String
    var direction : CLLocationDirection!
    var typeOfAnnotation : String!

    init(coordinate: CLLocationCoordinate2D, title : String, subTitle : String) {
        self.currentLocation = coordinate
        self._title = title
        self.subTitle = subTitle
    }

    func getLocation() -> CLLocation {
        return CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
    }

    var coordinate: CLLocationCoordinate2D {
        return self.currentLocation
    }

    var title : String {
        return self._title
    }

    var subtitle : String {
        return self.subTitle
    }
}

和我的ViewController文件 -

override func viewDidLoad() {
        super.viewDidLoad()

        var annotation1 : Annotation = Annotation(coordinate: location, title: name, subTitle: territory)
            annotation.typeOfAnnotation = PIN_ANNOTATION as String
            self.mapView.addAnnotation(annotation1)

         var annotation2 : Annotation = Annotation(coordinate: location, title: name, subTitle: territory)
            annotation.typeOfAnnotation = ARROW_ANNOTATION as String
            self.mapView.addAnnotation(annotation2)
    }


    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView!{
        let reuseId = "custom"
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)

        var customAnnotationView : MKAnnotationView!

        if let _annotation = annotation as? Annotation {
            if _annotation.typeOfAnnotation == PIN_ANNOTATION {
                customAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
                customAnnotationView.canShowCallout = true
                //customAnnotationView.draggable = true
            } else {
                customAnnotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)

                // 17 - Determine the direction
                let arrowImage = UIImage(named:"arrow")!
                let direction = _annotation.direction
                customAnnotationView.image = self.rotatedImage(arrowImage, byDegreesFromNorth: direction)
                customAnnotationView.canShowCallout = true
            }
        } else {
            return nil
        }

        return customAnnotationView
    }