Swift:MKAnnotation 长标题文本

标签 swift mkannotation

我有很长的 MKannotationView 标题文本。有没有一种简单的方法可以使标题中的文本大小合适?

reuseId = "Pin"
        var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
        pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        pinView!.image = UIImage(named:"pin")
        pinView?.canShowCallout = true
        pinView?.annotation
        let button : UIButton = UIButton(type: UIButtonType.DetailDisclosure)
        button.setImage(UIImage(named: "pin_arrow")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal), forState:UIControlState.Normal)
        pinView!.rightCalloutAccessoryView = button

        let vw: UIView = UIView(frame: CGRectMake(0, 0, 40, 50))
        let label: UILabel = UILabel(frame: CGRectMake(10, 0, 40, 50))
        label.font = UIFont.init(name: "Roboto-Bold", size: 20)
        label.textColor = UIColor(red:17/255.0, green:97/255.0, blue:172/255.0, alpha: 1.0)
        label.numberOfLines = 1
        for myObj in arrOfPinsOnMap where myObj.coordinate.latitude == pinView!.annotation!.coordinate.latitude && myObj.coordinate.longitude == pinView!.annotation!.coordinate.longitude && myObj.title == (pinView?.annotation?.title)!{
            label.text = myObj.sale
            if(myObj.sale != ""){
                vw.addSubview(label)
                if(label.text!.characters.count == 2){
                    vw.frame.size.width = 35
                    label.frame.size.width = 35
                } else if(label.text!.characters.count == 3){
                    vw.frame.size.width = 47
                    label.frame.size.width = 47
                } else if(label.text!.characters.count == 4){
                    label.frame.size.width = 67
                    vw.frame.size.width = 67
                } else if(label.text!.characters.count > 4){
                    label.frame.size.width = 80
                    vw.frame.size.width = 80
                }

                pinView!.leftCalloutAccessoryView = vw
            }
        }

我有这种方法可以在 PIN 上点击后显示 View 。我可以在左侧调整标签大小,但标题保持固定大小。标题必须始终可见。

最佳答案

如您所知,标准的 MapKit 标注有一个标题和左右辅助 View ,看起来您已经发现标注的标题在截断之前可以显示的文本数量有限,我们似乎无法访问标签 View 来更改它。

如果您能够针对 iOS 9 及更高版本,则标题下方会显示一个额外的 detailCalloutAccessoryView。不幸的是,您不能将标题留空并将所有文本放在详细信息 View 中,因为这样在点击时标注根本不会打开,因此您需要将某种文本放入标题中。

如果您无法让它工作,或者如果您需要支持 iOS 8,那么您将需要进行自定义标注。这并不难。创建一个 MKAnnotationView 子类,它具有您想要的标注外观,然后当您检测到在 mapView(_:didSelectAnnotationView:) 中点击标记时,添加特殊的标注注释与标记相同的位置。

这是一种方法:

class MyAnnotation: NSObject, MKAnnotation
{
    var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 49.5, longitude: -123.0)
    var title: String? = " "
}

class CalloutAnnotation: MyAnnotation { } // Special annotation class for the callout

let calloutRect = CGRect(origin: CGPointZero, size: CGSize(width: 200, height: 100))

class CalloutAnnotationView: MKAnnotationView
{
    var label: UILabel

    init()
    {
        label = UILabel(frame: CGRectInset(calloutRect, 8.0, 8.0))
        label.textAlignment = .Center
        label.numberOfLines = 0

        super.init(frame: calloutRect)

        self.addSubview(label)
        self.backgroundColor = UIColor.whiteColor()
        self.centerOffset = CGPoint(x: 0.0, y: -(calloutRect.size.height / 2))
        self.layer.cornerRadius = 6.0
    }

    required init?(coder aDecoder: NSCoder)
    {
        label = UILabel(frame: CGRectInset(calloutRect, 8.0, 8.0))
        super.init(coder: aDecoder)
    }
}

class ViewController: UIViewController, MKMapViewDelegate
{
    let calloutAnnotation = CalloutAnnotation()

    @IBOutlet weak var mapView: MKMapView!

    override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        mapView.addAnnotation(MyAnnotation())
    }

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
    {
        if annotation is CalloutAnnotation
        {
            let calloutView = CalloutAnnotationView()
            calloutView.label.text = "This is a custom callout that can look however you want."
            return calloutView
        }
        else
        {
            let reuseIdentifier = "pinView"
            let pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier) ??
                          MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)

            pinView.image = UIImage(named: "Pin")
            pinView.canShowCallout = false

            return pinView
        }
    }

    func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView)
    {
        if let coordinate = view.annotation?.coordinate
        {
            calloutAnnotation.coordinate = coordinate
            mapView.addAnnotation(calloutAnnotation)
        }
    }

    func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView)
    {
        mapView.removeAnnotation(calloutAnnotation)
    }
}

该 View 只是一个常规 View ,可以响应触摸等。这仍然不完美,因为当标注出现时您会丢失“弹出”动画,但如果需要,您可以通过更多工作将其添加回去到。我没有尝试过,但我确实在某一时刻得到了动画淡入淡出效果,所以我相当确定这是可能的。

关于Swift:MKAnnotation 长标题文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37425488/

相关文章:

ios - 在 iOS 中将大量且频繁的数据写入文件?

ios - 以编程方式生成顶点

ios - 带有 NSManagedObject 的 EVReflection 崩溃/不工作

ios - MKAnnotationView旋转

ios - 模拟器不支持框架 - 制作虚拟框架

ios - 找不到接受提供的参数的 'subscript' 的重载

ios - 检查用户是否在 map 中选择了另一个注释

iphone - 当前位置的自定义标注

iphone - 隐藏注释副标题,或更改颜色

ios - 更新时自定义注释不会在 map View 上更新