在用户位置标注上添加附件按钮
Adding accessory button on user location callout
我正在制作一个可点击的地标。我设置了地标的标题。标题是地址。我想如果你点击那个地址,它会推送到另一个视图以显示地址号码、城市、国家等。我试过这段代码。但是它在地标中的应用程序中没有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!")
}
}
}
您想在蓝点(用户位置)的标注上放置一个附件按钮。
在 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
时,此代码 returns nil
用于地图视图解释为 "display the default view and callout for this annotation"。默认标注仅显示标题和副标题。
创建自定义视图并设置 rightCalloutAccessoryView
的代码永远不会执行。
要设置 rightCalloutAccessoryView
,您需要引用实际注释 view object.
您可以删除 MKUserLocation
的 return nil
,但您会得到一个标准图钉而不是动画蓝点。
您无法创建自己的动画蓝点视图实例,因为 class 是私有的。
因此您无法在 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!")
}
}
我正在制作一个可点击的地标。我设置了地标的标题。标题是地址。我想如果你点击那个地址,它会推送到另一个视图以显示地址号码、城市、国家等。我试过这段代码。但是它在地标中的应用程序中没有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!")
}
}
}
您想在蓝点(用户位置)的标注上放置一个附件按钮。
在 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
时,此代码 returns nil
用于地图视图解释为 "display the default view and callout for this annotation"。默认标注仅显示标题和副标题。
创建自定义视图并设置 rightCalloutAccessoryView
的代码永远不会执行。
要设置 rightCalloutAccessoryView
,您需要引用实际注释 view object.
您可以删除 MKUserLocation
的 return nil
,但您会得到一个标准图钉而不是动画蓝点。
您无法创建自己的动画蓝点视图实例,因为 class 是私有的。
因此您无法在 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!")
}
}