【问题标题】:How do I change the image of an annotation for a coordinate?如何更改坐标注释的图像?
【发布时间】:2014-10-18 01:55:13
【问题描述】:

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

有人可以帮忙吗?谢谢!我一直在研究这个并阅读了大约一个星期,但我就是不明白。

【问题讨论】:

    标签: ios swift mapkit mkannotation mkannotationview


    【解决方案1】:

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

    创建地图视图后,设置其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)
    

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


    最后,关于:

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

    请注意,Xcode 只是让您编写和编译代码的 IDE。 iOS SDK 会知道正在使用哪个 iPhone。 SDK 可以根据屏幕大小自动调整视图大小。在文档、WWDC 视频、SO 或其他资源中搜索“Auto Layout”和/或“Size Classes”。

    【讨论】:

    • 谢谢!!!!我错过了添加委托,现在它可以工作了。谢谢! (现在要解决下一周的问题。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多