Mapkit iOS 9 Detailcalloutaccessoryview Usage

MapKit iOS 9 detailCalloutAccessoryView usage

You have to add some constraints for width and height of your view:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
var av = mapView.dequeueReusableAnnotationViewWithIdentifier("id")
if av == nil {
av = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "id")
}

let myView = UIView()
myView.backgroundColor = .greenColor()

let widthConstraint = NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 40)
myView.addConstraint(widthConstraint)

let heightConstraint = NSLayoutConstraint(item: myView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 20)
myView.addConstraint(heightConstraint)

av!.detailCalloutAccessoryView = myView
av!.canShowCallout = true

return av!
}

Munich 1972

Adding an intrinsicContentSize also works.

I did some testing and found out, that MapKit automagically sets translatesAutoresizingMaskIntoConstraints to false, when you set a view to detailCalloutAccessoryView.

In the WWDC 2015 session "What's New in MapKit" it was told, that "auto layout is supported". I reckon that Apple really means, that you have to use auto layout?!

Change color pin iOS 9 Mapkit

pinColor is deprecated in iOS 9, use pinTintColor instead.

Example:

let annotationView = MKPinAnnotationView()
annotationView.pinTintColor = UIColor.purpleColor()

Although the OP specifically asks for iOS 9, the following could ensure that the "non-deprecated" method prior to iOS 9 could be called:

if #available(iOS 9, *) {
annotationView.pinTintColor = UIColor.purpleColor()
} else {
annotationView.pinColor = .Purple
}

If your minimal target is iOS 9 as you specifically ask here, the above would then be redundant - Xcode would let you know that with a warning, as well, for your information.

iOS MapKit: tap in callout touches annotationView that is rendered under the callout

Found a solution (I did not find a solution using hitTest):

I now use my own UIView as callout (see Robs comment below the question as a start). That does not change my problem described in the question.

I noticed that I don't have the describd problem when I hit on the buttons in my callout view.

So I put an invisible custom button over all my non interactive labels and textViews. The infoButton shown below does nothing but catching taps. It has the same size as infoStackView below:

Sample Image

This solution should also work if annotationView.detailCalloutAccessoryView is used, as I did when I posed the question.

Detect on calloutAccessoryControlTapped only the tap on rightCalloutAccessoryView

To achieve it you would need to add target for the right accessory view. You can achieve it by setting button to rightCalloutAccessoryView as shown in the code snippet.

class MapViewController: UIViewController, MKMapViewDelegate {

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is Annotation {
let annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "reuseIdentifier")
let rightButton = UIButton(type: .DetailDisclosure)
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(_:)), forControlEvents: .TouchUpInside)
annotationView.rightCalloutAccessoryView = rightButton
}
return nil
}

func didClickDetailDisclosure(button: UIButton) {
// TODO: Perform action when was clicked on right callout accessory view.
}
}

// Helper classes.
class Annotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?

init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
}
}

class AnnotationView: MKAnnotationView {

}

how to show multiple lines in MKAnnotation with autolayout?

we can show multiple line in MKAnnotation view With the help of auto layout

it's very simple.

in objective c

 - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {

if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *customAnnotation = (CustomAnnotation *) annotation;

MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotation"];

if (annotationView == nil)
annotationView = customAnnotation.annotationView;
else
annotationView.annotation = annotation;

//Adding multiline subtitle code

UILabel *subTitlelbl = [[UILabel alloc]init];
subTitlelbl.text = @"sri ganganagar this is my home twon.sri ganganagar this is my home twon.sri ganganagar this is my home twon. ";

annotationView.detailCalloutAccessoryView = subTitlelbl;

NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:subTitlelbl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:150];

NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:subTitlelbl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0];
[subTitlelbl setNumberOfLines:0];
[subTitlelbl addConstraint:width];
[subTitlelbl addConstraint:height];

return annotationView;
} else
return nil;
}

output

Sample Image

For Swift

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

let identifier = "MyPin"

if annotation.isKindOfClass(MKUserLocation) {
return nil
}

var annotationView: MKPinAnnotationView? = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) as? MKPinAnnotationView

if annotationView == nil {

annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true

let label1 = UILabel(frame: CGRectMake(0, 0, 200, 21))
label1.text = "Some text1 some text2 some text2 some text2 some text2 some text2 some text2"
label1.numberOfLines = 0
annotationView!.detailCalloutAccessoryView = label1;

let width = NSLayoutConstraint(item: label1, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.LessThanOrEqual, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 200)
label1.addConstraint(width)

let height = NSLayoutConstraint(item: label1, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 90)
label1.addConstraint(height)

} else {
annotationView!.annotation = annotation
}
return annotationView
}

}

Sample Image

here i use NSLayoutConstraint

i programatically create a label. add the constraint on it and then add the label in detailCalloutAccessoryView of MKAnnotationView.



Related Topics



Leave a reply



Submit