在用户位置标注上添加附件按钮

时间:2015-05-12 21:01:44

标签: ios swift mapkit mkuserlocation

我正在制作一个可点击的地标。我设置了地标的标题。标题是地址。我想如果你点击那个地址它将推送到另一个视图显示地址编号,城市,国家等我试过这个代码。但它在地标中的应用还没有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!")
        }
    }
}

1 个答案:

答案 0 :(得分: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的代码永远不会执行。


要设置rightCalloutAccessoryView,您需要引用实际注释 view 对象。

您可以删除return nil的{​​{1}},但之后您将获得标准图钉而不是动画蓝点。

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

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


您可以可靠地访问实际用户位置注释视图的位置在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