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

我不明白如何更改
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
}

有人可以帮忙吗?谢谢!我一直在研究和阅读大约一个星期,我只是不明白.

最佳答案 从不调用viewForAnnotation方法,因为在viewDidLoad中以编程方式创建地图视图时未设置地图视图的委托.

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

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

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

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

请注意,必须完成在地图视图上设置委托属性以及声明视图控制器实现协议.

您还应该从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)

可能会崩溃,因为在调用startUpdatingLocation后,manager.location在这一点上可能仍然是nil.首先检查manager.location是否为nil或将该代码移动到didUpdateLocations委托方法会更安全.

最后,关于:

…I added the MKMapView programmatically to so I can switch sizes
(horizontal and vertical) based on which iPhone is being used. (I
still can’t believe this isn’t intuitive to Xcode and the programmer
has to program around it.)

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

点赞