我的sender.tag返回零

时间:2018-05-02 11:18:49

标签: swift uibutton mkmapview mkannotation

我的注释上有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加载宿舍因为注释被加载到地图中而起作用

1 个答案:

答案 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
    }

<强>输出:

enter image description here

符合上述所有步骤后,请符合您的要求:

let hostelTag = hostelsHelper.getTagForHostel(hostel)
print(hostelTag)

您获得Int值,如果不符合,则将其转换为正确的格式。我想它来了 nil 所以没有标签传递给按钮,你得到 nil 作为输出。

将来保持检查这样的空条件的习惯:

if let hostelTag = hostelsHelper.getTagForHostel(hostel){
   mapsButton.tag = hostelTag as? Int
}

这会阻止您为其指定 nil

希望这有帮助。