How to Make a Custom Mkannotationview with Xib

How to make a custom MKAnnotationView with XIB

UPDATED CODE BASED ON Sh-Khan's answer

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

// Don't want to show a custom image if the annotation is the user's location.
if (annotation is MKUserLocation) {
return nil
} else {

let annotationIdentifier = "AnnotationIdentifier"
let nibName = "MyAnnotationView"
let viewFromNib = Bundle.main.loadNibNamed(nibName, owner: self, options: nil)?.first as! MyAnnotationView
var annotationView: MyAnnotationView?

// if there is a view to be dequeued, use it for the annotation
if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) as? MyAnnotationView {

if dequeuedAnnotationView.subviews.isEmpty {
dequeuedAnnotationView.addSubview(viewFromNib)
}
annotationView = dequeuedAnnotationView
annotationView?.annotation = annotation
} else {

// if no views to dequeue, create an Annotation View
let av = MyAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
av.addSubview(viewFromNib)
annotationView = av // extend scope to be able to return at the end of the func
}

// after we manage to create or dequeue the av, configure it
if let annotationView = annotationView {
annotationView.canShowCallout = true // callout bubble
annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView.frame = CGRect(x: 0, y: 0, width: 40, height: 40)

let customView = annotationView.subviews.first as! MyAnnotationView
customView.frame = annotationView.frame
customView.textLabel.text = (annotationView.annotation?.title)!
}
return annotationView
}
}

How to use a custom XIB for MKAnnotationView?

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

// Don't want to show a custom image if the annotation is the user's location.
if (annotation is MKUserLocation) {
return nil
} else {

let annotationIdentifier = "AnnotationIdentifier"
var annotationView: MKPinAnnotationView?

if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "AnnotationIdentifier") as? MKPinAnnotationView {
//Here you can setup
annotationView = dequeuedAnnotationView
annotationView?.annotation = annotation
}

}

You don't need to initialize in on your own. It uses a custom CollectionViewCells. Try to use this example. (This is a delegate function FYI)

How to add a customView xib as annotation in Ios?

Try to add the object of the nib view to the annotation view like this

 func mapView(_ mapView: MKMapView,viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
if annotation is MKUserLocation == true
{

return nil
}

let senderAnnotation = annotation as! MyAnnotation

let pinReusableIdentifier = senderAnnotation.pinColor.rawValue

var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinReusableIdentifier)

if annotationView == nil
{

annotationView = MKAnnotationView(annotation: senderAnnotation, reuseIdentifier: pinReusableIdentifier)
annotationView!.canShowCallout = true

}

let customView = (Bundle.main.loadNibNamed("directOrderView", owner: self, options: nil))?[0] as! directOrderView;

var calloutViewFrame = customView.frame;
calloutViewFrame.origin = CGPoint(x:-calloutViewFrame.size.width/2 + 30,y: -calloutViewFrame.size.height);
customView.frame = calloutViewFrame;

annotationView?.addSubview(customView)

return annotationView

}

Custom callout view with xib

In didSelectAnnotationView load xib from bundle and add subview to the annotation view. here CustomXibCallout is xib file and CustomCalloutView is MKAnnotationView.

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
if view.annotation!.isKindOfClass(MKUserLocation){
return
}

//Custom xib
let customView = (NSBundle.mainBundle().loadNibNamed("CustomXibCallout", owner: self, options: nil))[0] as! CustomCalloutView;

let calloutViewFrame = customView.frame;

customView.frame = CGRect(x: -calloutViewFrame.size.width/2.23, y: -calloutViewFrame.size.height-7, width: 315, height: 200)

view.addSubview(customView)
}

in didDeselectAnnotationView remove the added view

func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView)
{
for childView:AnyObject in view.subviews{
childView.removeFromSuperview();
}
}

Example for CustomCallout

How to set .xib interface as a custom callout view?

you can show custom callout view like this in Swift.

func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKPinAnnotationView!)
{
if view.annotation.isKindOfClass(MKUserLocation){
return
}

var customView = (NSBundle.mainBundle().loadNibNamed("SubView", owner: self, options: nil))[0] as CustomSubView;

var calloutViewFrame = customView.frame;
calloutViewFrame.origin = CGPointMake(-calloutViewFrame.size.width/2 + 15, -calloutViewFrame.size.height);
customView.frame = calloutViewFrame;

let cpa = view.annotation as CustomPointAnnotation
//You can add set vlaues for here
//cpa.title
//cpa.postCode
//cpa.street

view.addSubview(customView)

//zoom map to show callout
let spanX = 0.0000000000000001
let spanY = 0.0000000000000001

var newRegion = MKCoordinateRegion(center:cpa.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
self.map?.setRegion(newRegion, animated: true)
}


Related Topics



Leave a reply



Submit