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!
}
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:
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
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
}
}
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
Fbsopenapplicationerrordomain Code =4 Error
Swift Framework: Umbrella Header '[...].H' Not Found
Avcapturevideopreviewlayer Orientation - Need Landscape
How to Calculate the Age Based on Nsdate
Move a View When Scrolling in Uitableview
Expanding and Collapsing Table View Cells in iOS
Show Search Bar in Navigation Bar Without Scrolling on iOS 11
--Resource-Rules Has Been Deprecated in MAC Os X >= 10.10
How to Use Cocoapods When Creating a Cocoa Touch Framework
How to Create a Release Build in Xcode
Xcode 4.2 Jumps to Main.M Every Time After Stopping Simulator
Getting Device Id or MAC Address in iOS
Uicollectionview Horizontal Paging Not Centered
Detecting If a User Is Moving in a Car