2

我正在制作一个可点击的地标。我设置了地标的标题。标题是地址。我想如果您单击该地址,它将推送到另一个视图以显示地址编号、城市、国家等。我尝试了此代码。但是地标中的应用程序中没有UIButton,为什么?

编辑:如果我将断点设置为 func calloutAccessoryControlTapped 它不会崩溃。

func mapView(Mapa: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

    if annotation is MKUserLocation {
        //return nil so map view draws "blue dot" for standard user location
        return nil
    }

    var pin = "pin"

    var view = Mapa.dequeueReusableAnnotationViewWithIdentifier(pin) as? MKPinAnnotationView
    if view == nil {
        view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pin)
        view!.canShowCallout = true
        view!.animatesDrop = true
        var arrowButton = UIButton()
        view!.rightCalloutAccessoryView = UIButton.buttonWithType(.DetailDisclosure) as! UIButton
    } else {
        view!.annotation = annotation
    }
    return view
}

func mapView(Mapa: MKMapView!, annotation: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    if control == annotation.rightCalloutAccessoryView {
        println("Pressed!")
    }
}

整个代码:

import UIKit
import CoreLocation
import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {

    @IBOutlet weak var Mapa: MKMapView!
    let locationManager = CLLocationManager()
    var detail: UIButton!

    override func viewDidLoad()
    {
        super.viewDidLoad()


        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()



        Mapa.delegate = self
        Mapa.mapType = MKMapType.Standard
        Mapa.showsUserLocation = true


    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()

    }



    //--- Find Address of Current Location ---//

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    {
        //--- CLGeocode to get address of current location ---//
        CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
            let spanX = 0.007
            let spanY = 0.007
            var newRegion = MKCoordinateRegion(center: self.Mapa.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
            self.Mapa.setRegion(newRegion, animated: true)


            if (error != nil)
            {
                println("Reverse geocoder failed with error" + error.localizedDescription)
                return
            }

            if placemarks.count > 0
            {
                let pm = placemarks[0] as! CLPlacemark
                self.displayLocationInfo(pm)
            }
            else
            {
                println("Problem with the data received from geocoder")
            }
        })

    }


    func displayLocationInfo(placemark: CLPlacemark?)
    {
        if let Placemark = placemark
        {
            //Stop updating kvôli vydrži baterke
            locationManager.stopUpdatingLocation()
            let location = self.locationManager.location
            var latitude: Double = location.coordinate.latitude
            var longitude: Double = location.coordinate.longitude
            let adresa = (Placemark.thoroughfare != nil) ? Placemark.thoroughfare : "Ulica: "
            let cislo = (Placemark.subThoroughfare != nil) ? Placemark.subThoroughfare : "Číslo ulice:"
            let mesto = (Placemark.locality != nil) ? Placemark.locality : "Mesto: "
            let stat = (Placemark.country != nil) ? Placemark.country : "Štát: "




            var coordinates:CLLocationCoordinate2D = placemark!.location.coordinate
            let theLocation: MKUserLocation = Mapa.userLocation
            theLocation.title = adresa




            println("GPS Súradnice :: \(latitude), \(longitude)")
            println(mesto)
            println(adresa)
            println(cislo)
            println(stat)

        }

    }

    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!)
    {
        println("Chyba pri aktualizovaní lokácie " + error.localizedDescription)
    }

    func mapView(Mapa: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        if annotation is MKUserLocation {
            //return nil so map view draws "blue dot" for standard user location
            return nil
        }

        var pin = "pin"

        var view = Mapa.dequeueReusableAnnotationViewWithIdentifier(pin) as? MKPinAnnotationView
        if view == nil {
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pin)
            view!.canShowCallout = true
            view!.animatesDrop = true
            var arrowButton = UIButton()
            view!.rightCalloutAccessoryView = UIButton.buttonWithType(.DetailDisclosure) as! UIButton
        } else {
            view!.annotation = annotation
        }
        return view
    }

    func mapView(Mapa: MKMapView!, annotation: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

        if control == annotation.rightCalloutAccessoryView {
            println("Pressed!")
        }
    }
}
4

1 回答 1

1

您想在蓝点(用户位置)的标注上放置一个附件按钮。

viewForAnnotation委托方法中,您确实有创建注释视图并设置的代码,rightCalloutAccessoryView但在方法的顶部有以下代码:

func mapView(Mapa: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

    if annotation is MKUserLocation {
        //return nil so map view draws "blue dot" for standard user location
        return nil
    }

地图的用户位置注释属于类型MKUserLocation,因此当地图视图调用viewForAnnotation它时,此代码nil会为其返回,地图视图将其解释为“显示此注释的默认视图和标注”。默认标注仅显示标题和副标题。

创建自定义视图和设置的代码rightCalloutAccessoryView永远不会执行。


要设置 a rightCalloutAccessoryView,您需要对实际注释视图对象的引用。

您可以将其删除,return nilMKUserLocation随后您将获得标准图钉而不是动画蓝点。

您不能创建自己的动画蓝点视图实例,因为该类是私有的。

因此,您无法在viewForAnnotation委托方法中创建或访问用户位置注释视图。


您可以可靠地访问实际用户位置注释视图的地方是didAddAnnotationViews委托方法。我建议使用这种方法,因为这意味着实际上已经创建了一个注释视图并且在屏幕上。

在此方法中,调用地图视图的viewForAnnotation实例方法并将其userLocation注释传递给它,然后设置视图的rightCalloutAccessoryView

func mapView(mapView: MKMapView!, didAddAnnotationViews views: [AnyObject]!) {
    if let ulav = mapView.viewForAnnotation(mapView.userLocation) {
        ulav.rightCalloutAccessoryView = UIButton.buttonWithType(.DetailDisclosure) as! UIButton
    }
}


与未出现的标注按钮无关,但是:
您的calloutAccessoryControlTapped委托方法命名错误,并且在点击按钮时不会被调用。

您的方法名为mapView(annotation:calloutAccessoryControlTapped).

annotation参数必须命名annotationView,即使命名地图视图参数Mapa将起作用,我建议坚持文档中给出的签名,因此修改后的方法是:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
    if control == annotationView.rightCalloutAccessoryView {
        println("Pressed!")
    }
}
于 2015-05-13T11:33:37.397 回答