Добавление вспомогательной кнопки на выноску местоположения пользователя

Я делаю кликабельную метку. Я установил название метки. Название - адрес. Я хочу, если вы нажмете на этот адрес, он переместится в другой вид, чтобы показать номер адреса, город, страну и т. Д. Я попробовал этот код. Но это не 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 ответ

Решение

Вы хотите поместить вспомогательную кнопку в выноску синей точки (местоположение пользователя).

в 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, вам нужна ссылка на фактический объект представления аннотации.

Вы можете удалить это return nil для 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 будет работать, я предлагаю придерживаться подписи, приведенной в документации, чтобы пересмотренный метод был:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
    if control == annotationView.rightCalloutAccessoryView {
        println("Pressed!")
    }
}
Другие вопросы по тегам