MKPinAnnotationView 不显示标题

Posted

技术标签:

【中文标题】MKPinAnnotationView 不显示标题【英文标题】:MKPinAnnotationView not showing title 【发布时间】:2016-12-23 03:45:05 【问题描述】:

我有一些使用MKMapViewMKPointAnnotation 的经验,我曾经在地图上放置一些图钉。 这次我想更进一步,使用MKPinAnnotationView,写一个标签和一些别针。

不幸的是,它并没有像我预期的那样工作。

这是我想做的:

我有一张地图(一个 MKMapView 对象),当我触摸它时,我在触摸点上放了一个大头针,然后执行一些计算,这给了我地图上的第二个点。我放了第二个图钉(位于第二个点),在最后一个图钉上我想贴一个标签,说“Hello Second!”。

以下是相关代码:

class ViewController: UIViewController, MKMapViewDelegate 
    var mapView:MKMapView!, touchPoint,secondPoint:MKPointAnnotation!

    override func viewDidLoad() 
        super.viewDidLoad()
        mapView = MKMapView()
        ...........
        let mapTap = UITapGestureRecognizer(target: self,
                                            action: #selector(ViewController.mapTouchHandler))
        mapView.addGestureRecognizer(mapTap)
    


    func mapTouchHandler(gesture:UITapGestureRecognizer) 
        ...........
        // Compute map coordinates for the touch point (tapGeoPoint).

        if touchPoint == nil 
            touchPoint = MKPointAnnotation()
            mapView.addAnnotation(touchPoint);
        

        touchPoint.coordinate = CLLocationCoordinate2D(latitude: tapGeoPoint.latitude,
                                                       longitude: tapGeoPoint.longitude)
        ...........
        computeSecondPoint(url: someComputedURL)
    


    func computeSecondPoint(url searchURL:String) 
        let reqURL = NSURL(string: searchURL)!, session = URLSession.shared,
        task = session.dataTask(with: reqURL as URL) 
            (data: Data?, response: URLResponse?, error: Error?) in
            if error == nil 
                do let allData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray
                    .................
                    // Compute map coordinates for the second point (secondPointCoord).

                    if self.secondPoint == nil 
                        self.secondPoint = MKPointAnnotation()
                        self.mapView.addAnnotation(self.secondPoint)
                    

                    DispatchQueue.main.async 
                        () -> Void in
                        self.secondPoint.coordinate = CLLocationCoordinate2D(latitude: secondPointCoord.latitude,
                                                                             longitude: secondPointCoord.longitude)
                        self.secondPoint.title = "Hello Second!"
                    
                 catch let error as NSError print(error.localizedDescription)
             else 
                print("Error inside \(#function):\n\(error)")
            
        

        task.resume()

    


    func mapView(_ mapView: MKMapView,
                 viewFor annotation: MKAnnotation) -> MKAnnotationView? 
        let identifier = "pin"
        var view: MKPinAnnotationView
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
            as? MKPinAnnotationView 
            dequeuedView.annotation = annotation
            view = dequeuedView
         else 
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            view.canShowCallout = true
            view.calloutOffset = CGPoint(x: -5, y: 0)
        
        return view
    

现在发生的情况是,引脚按预期放置,但我在第二个上看不到任何标签。 我还注意到,如果我点击第二个大头针恰好在的位置(在这种情况下,第二个大头针将保持在同一个地方),那么标签就会出现(就像它应该总是做的那样)。如果我再次点击(不是那么近),那么标签会再次消失(尽管它不应该)。

我的代码(上图)中有什么不正确的地方吗? 任何相关提示将不胜感激。

【问题讨论】:

【参考方案1】:

你在

中引用的标题
self.secondPoint.title = "Hello Second!"

是当您点击注释图钉时出现的标注视图的标题。如果您想每次都显示标签和图钉图像,您可以继承MKAnnotationView 并在您的自定义图钉视图中添加标签。您可以通过以下方式自定义

class CustomAnnotationView : MKPinAnnotationView

    let helloLabel:UILabel = UILabel.init(frame:CGRectMake(0, 0, 100, 40)) //your desired frame

    func showLabel(title : String)
    
        helloLabel.text = title
        helloLabel.textAlignment = .Center
        //set further properties
        self.addSubview(helloLabel)
    

    fun hideLabel() 
        helloLabel.removeFromSuperview()
    

【讨论】:

我花了一些时间来试验你的建议,这对我理解所有这些是如何工作的有很大帮助。这是我现在的问题:当函数“func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?”叫做。我怎么知道它是为 touchPoint 还是为 secondPoint 调用的? MKPointAnnotation 和 MKAnnotation 之间是否有链接或我可以使用的东西。 @Michel 您可以通过简单的if(annotation == touchPoint) //do somethingelse if(annotation == secondPoint) //do something else 检查所点击的注释是否是一个或另一个。希望对你有帮助 @Reinier:这不起作用,因为注释是 MKAnnotation 类型,而 touchPoint 是 MKPointAnnotation 类型;您收到编译器的投诉。但我找到了一种不同的方法:使用此代码比较坐标“if ((annotation.coordinate.latitude != touchPoint.coordinate.latitude) || (annotation.coordinate.longitude != touchPoint.coordinate.longitude)) . ..”。坦率地说,我不喜欢它,但我现在没有比这更好的了。 @Vishnu:按照您的提示,我现在可以将标签与图钉一起放置并显示一些东西。我希望能够在更改相应的引脚坐标时修改此标签的内容。换句话说(参考我的帖子),当我写:self.secondPoint.title =“Hello Second!”时,我想为标签设置一个新内容,例如:self.secondPoint_Annotation.showLabel(“我的新标签” ”)。问题是我不知道如何获取 secondPoint_Annotation(来自 secondPoint)。 自从我在这里取得了一些进展。考虑到我在这里学到的知识,我在此链接重新提出了问题:***.com/questions/41311327/…。【参考方案2】:

试试这个解决方案这对你有帮助

首先创建 MyAnnotation pin

if(geo_accuracy == "0")
            
                colorofpin = .Blue
            else if (geo_accuracy == "1")
            
                colorofpin = .Red
            else
            
                colorofpin = .Green
            
            var locationAnnotation = MyAnnotation(coordinate: location,
                title: p_user_name!,
                subtitle: "",
                pinColor: colorofpin,
                getTag:i)


            /* And eventually add them to the map */

            //aryNotation.addObject(locationAnnotation)

            aryNotation.append(locationAnnotation)

mapview 委托方法

func mapView(mapView: MKMapView,
        viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?

            if annotation is MyAnnotation == false
                return nil
            

            /* First typecast the annotation for which the Map View has
            fired this delegate message */
            let senderAnnotation = annotation as! MyAnnotation



            // --------------------------    For ios 9 -------------------


            let reuseId = "pin"
            var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)

            if pinView == nil 
                pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
                pinView!.canShowCallout = true

            else
                pinView!.annotation = annotation
            
            pinView!.tag = senderAnnotation.getTag;

          //  print(senderAnnotation.getTag)

            if annotation is MyAnnotation 

                //print(senderAnnotation.pinColor)
                if(senderAnnotation.pinColor == .Red)
                
                    if(currentIndex == senderAnnotation.getTag)
                    
                        //print("currentIndex==\(currentIndex)********")
                        pinView!.image = UIImage(named: "jivemap_pin_rough_o.png")
                        pinView!.layer.zPosition = 1
                        pinView?.bringSubviewToFront(self.view)
                       // pinView!.superview!.bringSubviewToFront(view)
                    else
                    
                        pinView!.image = UIImage(named: "jivemap_pin_rough_g.png")
                        pinView!.layer.zPosition = 0
                    
                
                else
                

                if(currentIndex == senderAnnotation.getTag)
                
                    //print("currentIndex==*********\(currentIndex)********")
                    pinView!.image = UIImage(named: "jivemap_pin_o.png")
                    pinView!.layer.zPosition = 1


                else
                
                    pinView!.image = UIImage(named: "jivemap_pin_g.png")
                    pinView!.layer.zPosition = 0
                
            

                pinView!.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure) as UIView
              // pinView
               // return pinView
            





            return pinView
            //return annotationView

    

这是我的国庆课。这门课将解决你所有的问题

import UIKit
import MapKit

/* This will allow us to check for equality between two items
of type PinColor */
func == (left: PinColor, right: PinColor) -> Bool
    return left.rawValue == right.rawValue


/* The various pin colors that our annotation can have */
enum PinColor : String
    case Blue = "Blue"
    case Red = "Red"
    case Green = "Green"
    case Purple = "Purple"

    /* We will convert our pin color to the system pin color */
    func toPinColor() -> MKPinAnnotationColor
        switch self
        case .Red:
            return .Red
        case .Green:
            return .Green
        case .Purple:
            return .Purple
        default:
            /* For the blue pin, this will return .Red but we need
            to return *a* value in this function. For this case, we will
            ignore the return value */
            return .Red
        
    


class MyAnnotation: NSObject, MKAnnotation 
    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?
    var pinColor: PinColor!
    var getTag:Int!
    var annoationIndex = 0

    init(coordinate: CLLocationCoordinate2D,
        title: String,
        subtitle: String,
        pinColor: PinColor,
        getTag: Int)
            self.coordinate = coordinate
            self.title = title
            self.subtitle = subtitle
            self.pinColor = pinColor
            self.getTag = getTag
            super.init()
    

    convenience init(coordinate: CLLocationCoordinate2D,
        title: String,
        subtitle: String,
        gettag: Int)
            self.init(coordinate: coordinate,
                title: title,
                subtitle: subtitle,
                pinColor: .Blue,
                getTag: gettag)
    


【讨论】:

【参考方案3】:

这个我已经用于谷歌地图,但它应该对你有用..

let position = CLLocationCoordinate2DMake(latitude,longitude)
let location = GMSMarker(position: position)
location.icon = image
location.icon? = self.imageWithImage(image, scaledToSize: CGSize(width: 50.0, height: 50.0))
location.title = "the photo is clicked here!!"
location.map = MapView

【讨论】:

好吧,我不应该使用不同的 SDK(Google Maps API)来做到这一点。我想如果我以正确的方式做事,它应该可以按我的意愿工作。 我只是给你一个粗略的想法,我并不是要求使用谷歌地图。

以上是关于MKPinAnnotationView 不显示标题的主要内容,如果未能解决你的问题,请参考以下文章

MKPinAnnotationView 颜色不起作用

MKPinAnnotationView 不在 MKMapView 中显示,即使它是使用 Swift 正确添加的

MKPinAnnotationView 的不同颜色取决于时间

不同时显示 MKPinAnnotationView

MKPinAnnotationView - 不同引脚的不同动作

MKPinAnnotationView 子视图不更新