如何更改坐标注释的图像?

时间:2014-10-18 01:55:13

标签: ios swift mapkit mkannotation mkannotationview

我不明白如何更改Swift中标记点的图像。我尝试了一些

的变体
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! 

但它似乎永远不会被调用,我不知道如何强制它被调用。

我会说我也以编程方式添加了MKMapView所以我可以根据使用的iPhone来切换大小(水平和垂直)。 (我仍然无法相信这对Xcode来说并不直观,程序员必须围绕它进行编程。)

这是我的代码:

@IBAction func addStroke(sender: UIButton) {
    NSLog("Add Stroke Touched")
    NSLog("X %f Y %f", manager.location.coordinate.latitude, manager.location.coordinate.longitude)
    GPSspot = manager.location.coordinate

    annotation.setCoordinate(GPSspot)
    annotation.title = "Stroke"

    let useID = "test"

    var myAnnotation = mapHole.dequeueReusableAnnotationViewWithIdentifier(useID)
    if (myAnnotation == nil) {
        myAnnotation = MKAnnotationView(annotation: annotation, reuseIdentifier: useID)
        myAnnotation.image = UIImage(named: "ballSmall.png")
        myAnnotation.canShowCallout = true
        myAnnotation.enabled = true
    } else {
        myAnnotation.annotation = annotation
    }

    mapHole.viewForAnnotation(annotation)
    mapHole.addAnnotation(annotation)
}

//MARK: - Map Kit
var mapRect = MMRect(xLoc: 502, yLoc:20, yWidth:218, xHeight:386)
var mapHole:MKMapView! //= MKMapView() as MKMapView
var annotation = MKPointAnnotation()
var MAView:MKAnnotationView!

//MARK: - GPS Locations
var manager:CLLocationManager!
var GPSspot:CLLocationCoordinate2D!
var span:MKCoordinateSpan!
var region:MKCoordinateRegion!

//MARK: - Default Initializer
override func viewDidLoad() {
    super.viewDidLoad()

    //MARK: Locations
    manager = CLLocationManager()
    if (CLLocationManager.locationServicesEnabled()) {
        NSLog("locations services started")
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.requestAlwaysAuthorization()
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
    } else {
        NSLog("location services failed")
    }


    //MARK: MKMapView
    mapHole = MKMapView(frame: mapRect.textRect)
    span = MKCoordinateSpanMake(0.001, 0.001)
    GPSspot = manager.location.coordinate
    region = MKCoordinateRegion(center: GPSspot, span: span)
    mapHole.setRegion(region, animated: true)
    mapHole.mapType = MKMapType.Satellite
    mapHole.showsUserLocation = true
    self.view.addSubview(mapHole)
}

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    if annotation is MKUserLocation {
        return nil
    }

    let reuseId = "test"

    var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
    if anView == nil {
        anView = MKAnnotationView (annotation: annotation, reuseIdentifier: reuseId)
        anView.image = UIImage(named:"ballSmall.png")
        anView.canShowCallout = true
    } else {
        anView.annotation = annotation
    }

    return anView
}

有人可以帮忙吗?谢谢!我一直在研究这个问题并且阅读了大约一个星期了,而我却得不到它。

1 个答案:

答案 0 :(得分:2)

viewForAnnotation方法永远不会被调用,因为在delegate中以编程方式创建地图视图时未设置地图视图的viewDidLoad

创建地图视图后,设置其delegate属性:

mapHole = MKMapView(frame: mapRect.textRect)
mapHole.delegate = self                       // <-- add this line
span = MKCoordinateSpanMake(0.001, 0.001)

此外,如果您还没有,则必须声明视图控制器实现MKMapViewDelegate协议。例如:

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

请注意,必须在地图视图上设置delegate属性,并声明视图控制器实现协议。


您还应该从addStroke方法中删除与视图相关的代码,因为它不属于那里,没有效果,并且没有意义:

annotation.title = "Stroke"

/* This code doesn't belong here...
let useID = "test"

var myAnnotation = mapHole.dequeueReusableAnnotationViewWithIdentifier(useID)
if (myAnnotation == nil) {
    myAnnotation = MKAnnotationView(annotation: annotation, reuseIdentifier: useID)
    myAnnotation.image = UIImage(named: "ballSmall.png")
    myAnnotation.canShowCallout = true
    myAnnotation.enabled = true
} else {
    myAnnotation.annotation = annotation
}

mapHole.viewForAnnotation(annotation)
*/

mapHole.addAnnotation(annotation)


另请注意viewDidLoad中的此代码:

GPSspot = manager.location.coordinate
region = MKCoordinateRegion(center: GPSspot, span: span)
mapHole.setRegion(region, animated: true)

可能会崩溃,因为manager.location在调用nil后很快就会startUpdatingLocation。首先检查manager.location是否不是nil或将该代码移至didUpdateLocations委托方法会更安全。


最后,关于:

  

...我以编程方式添加了MKMapView,以便我可以切换大小   (水平和垂直)基于iPhone的使用。 (一世   仍然无法相信这对Xcode和程序员来说并不直观   必须围绕它进行编程。)

请注意,Xcode只是让您编写和编译代码的IDE。这是iOS SDK,可以了解正在使用的iPhone。 SDK可以根据屏幕大小自动调整视图大小。在文档,WWDC视频,SO或其他资源中搜索“自动布局”和/或“大小类”。