问题
I have long MKannotationView title text. Is there an easy way to give Text in title proper size?
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
}
}
I have this method for showing View after TAP on pin. I can adjust my Label size on left side, but title remain fixed size. The title must be always visible.
回答1:
As you know, standard MapKit callouts have a title and left and right accessory views, and it looks like you've discovered that the title of a callout has a limited amount of text that you can show before it truncates, and we don't seem to get access to the label view to change that.
If you are able to target iOS 9 and above, there is an additional detailCalloutAccessoryView
which is shown below the title. Unfortunately, you can't just leave the title blank and put all your text in the detail view because then the callout doesn't open at all when tapped, so you need to put some sort of text into the title.
If you can't get that to work or if you need to support iOS 8, then you'll need to do a custom callout. This isn't that difficult. Create an MKAnnotationView
subclass that has the appearance you want for a callout and then when you detect a marker being tapped in mapView(_:didSelectAnnotationView:)
add the special callout annotation at the same location as the marker.
Here's one way to do it:
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)
}
}
The view is just a regular view and can respond to touches etc. This is still not perfect because you lose the 'pop' animation when the callout appears, but you can probably add that back with a bit more work if you need to. I've not tried that, but I did get a fade in animation working at one point, so I'm fairly sure it's possible.
来源:https://stackoverflow.com/questions/37425488/swift-mkannotation-long-title-text