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は実行されません。


を設定するには、実際の注釈ビューオブジェクトrightCalloutAccessoryViewへの参照が必要です。

を削除することもできreturn nilますMKUserLocationが、アニメーション化された青い点の代わりに標準のピンが表示されます。

そのクラスはプライベートであるため、アニメーション化された青いドット ビューの独自のインスタンスを作成することはできません。

viewForAnnotationそのため、デリゲート メソッドでユーザー位置注釈ビューを作成したり、アクセスしたりすることはできません。


実際のユーザー位置の注釈ビューに確実にアクセスできる場所は、didAddAnnotationViewsデリゲート メソッドです。注釈ビューが実際に作成され、画面上にあることを意味するため、この方法をお勧めします。

このメソッドでは、マップ ビューのインスタンス メソッドを呼び出し、そのアノテーションをviewForAnnotation渡し、ビューの を設定します。userLocationrightCalloutAccessoryView

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 に答える