我的注释上有2个按钮,一个用于导航,另一个用于呼叫。但是当我点击按钮时它根本不起作用,因为sender.tag返回nil。我无法在网上找到如何以正确的方式为注释设置sender.tag。
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {return nil}
let reuseId = "Pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
let annotitle = annotation.title ?? ""
let annosubtitle = annotation.subtitle ?? ""
let title = annotitle ?? ""
let phone = annosubtitle ?? ""
let type = annotation.description
let hostel = Hostel(location: annotation.coordinate, title: title, phone: phone, type: type)
let hostelTag = hostelsHelper.getTagForHostel(hostel)
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
pinView!.pinTintColor = UIColor.black
let mapsButton = UIButton(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30)))
mapsButton.setBackgroundImage(UIImage(named: "Maps-icon"), for: UIControlState())
mapsButton.tag = hostelTag
pinView!.leftCalloutAccessoryView = mapsButton
pinView!.leftCalloutAccessoryView?.tintColor = UIColor.black
mapsButton.addTarget(self, action: #selector (MapViewController.didClickRouteButton(sender: )), for: .touchUpInside)
if !phone.isEmpty {
let callButton = UIButton(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30)))
callButton.setBackgroundImage(UIImage(named: "call icon round"), for: UIControlState())
callButton.tag = hostelTag
pinView!.rightCalloutAccessoryView = callButton
pinView!.rightCalloutAccessoryView?.tintColor = UIColor.black
callButton.addTarget(self, action: #selector (MapViewController.didClickCallButton(sender: )), for: .touchUpInside)
}
pinView!.sizeToFit()
}
else {
pinView!.annotation = annotation
}
return pinView
}
// pinButton actions
@objc func didClickRouteButton(sender: UIButton) {
let placemark : MKPlacemark = MKPlacemark(coordinate: hostelsHelper.getLocationFor(sender.tag))
let mapItem:MKMapItem = MKMapItem(placemark: placemark)
mapItem.name = hostelsHelper.getTitleFor(sender.tag)
mapItem.phoneNumber = hostelsHelper.getPhoneFor(sender.tag)
let launchOptions:NSDictionary = NSDictionary(object: MKLaunchOptionsDirectionsModeDriving, forKey: MKLaunchOptionsDirectionsModeKey as NSCopying)
let currentLocationMapItem:MKMapItem = MKMapItem.forCurrentLocation()
MKMapItem.openMaps(with: [currentLocationMapItem, mapItem], launchOptions: launchOptions as? [String : Any])
print ("Navigation to:\(hostelsHelper.getTitleFor(sender.tag))")
}
@objc func didClickCallButton(sender: UIButton) -> Void {
if let url = URL(string: "tel://\(hostelsHelper.getPhoneFor(sender.tag))") {
UIApplication.shared.open(url, options: [:])
}
print ("calling:\(hostelsHelper.getTitleFor(sender.tag))")
}
如果有人可以帮助我,那就太棒了!
我的hostelHelper功能如下:
import Foundation
import MapKit
struct Hostel {
var location: CLLocationCoordinate2D
var title: String
var phone: String
var type: String
}
extension Hostel: Equatable {}
func ==(lhs: Hostel, rhs: Hostel) -> Bool {
return lhs.location.latitude == rhs.location.latitude && lhs.location.longitude == rhs.location.longitude && lhs.title == rhs.title && lhs.phone == rhs.phone && lhs.type == rhs.type
}
class HostelsHelper {
private var hostels: [Hostel]
init() {
hostels = [Hostel]()
if let cityDetailsPath = Bundle.main.path(forResource: "Hostels", ofType: "plist") {
guard let cityDetails = NSArray(contentsOfFile: cityDetailsPath) as? [[String: String]] else {return}
for city in cityDetails
{
guard let latStr = city["latitude"] else { continue }
guard let lonStr = city["longitude"] else { continue }
guard let titleStr = city["title"] else { continue }
guard let phoneStr = city["subTitle"] else { continue }
guard let typeStr = city["type"] else { continue }
if let lat = Double(latStr) {
if let lon = Double(lonStr) {
let coordinate = CLLocationCoordinate2DMake(lat,lon)
hostels.append(Hostel(location: coordinate, title: titleStr, phone: phoneStr, type: typeStr))
}
}
}
}
}
func getTagForHostel(_ hostel: Hostel) -> Int {
return hostels.index(of: hostel ) ?? -1
}
func getHostelsCount() -> Int {
return hostels.count
}
func getPhoneFor(_ tag: Int) -> String {
return tag != -1 ? hostels[tag].phone : ""
}
func getTypeFor(_ tag: Int) -> String {
return tag != -1 ? hostels[tag].type : ""
}
func getTitleFor(_ tag: Int) -> String {
return tag != -1 ? hostels[tag].title : ""
}
func getLocationFor(_ tag: Int) -> CLLocationCoordinate2D {
return tag != -1 ? hostels[tag].location : kCLLocationCoordinate2DInvalid
}
}
并且从.plist加载宿舍因为注释被加载到地图中而起作用
答案 0 :(得分:0)
要将标记设置为UIButton
,需要执行以下步骤。
在我的情况下,我将标签设置为viewDidLoad()
中的按钮,您可以将其设置在任何位置。
@IBOutlet weak var btnAgenda: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
btnAgenda.tag = 5
// Do any additional setup after loading the view.
}
@IBAction func btnAgendaClicked(_ sender: UIButton) {
print(sender.tag) // 5
}
<强>输出:强>
符合上述所有步骤后,请符合您的要求:
let hostelTag = hostelsHelper.getTagForHostel(hostel)
print(hostelTag)
您获得Int
值,如果不符合,则将其转换为正确的格式。我想它来了 nil 所以没有标签传递给按钮,你得到 nil 作为输出。
将来保持检查这样的空条件的习惯:
if let hostelTag = hostelsHelper.getTagForHostel(hostel){
mapsButton.tag = hostelTag as? Int
}
这会阻止您为其指定 nil 值
希望这有帮助。