1

I'm trying to set a custom callout view with a xib I created however it doesn't show up.

My xib LocationInfo looks like this enter image description here

I've created a custom uiview class for the view in my xib to set a background image (not sure if this works since I haven't been able to show the xib)

import Foundation
import UIKit
import MapKit

class AddressView: MKPinAnnotationView{
    override func draw(_ rect: CGRect) {
        super.draw(rect);

        UIGraphicsBeginImageContext(self.frame.size)
        UIImage(named: "Location.Info-background")?.draw(in: self.bounds)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.backgroundColor = UIColor(patternImage: image!)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        //todo
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        //todo
        return nil
    }
}

My custom annotationpin class is as follows

import Foundation
import MapKit
import UIKit

class MapPin: MKPointAnnotation{
    var name: String
    var street: String
    var type: String
    var postCode: String

    init(name: String, street: String, type: String, postCode: String){
        self.name = name
        self.street = street
        self.type = type
        self.postCode = postCode
    }
}

and I'm trying to use this all as follows in my view controller class

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        CLGeocoder().reverseGeocodeLocation(manager.location!) { (placemarks, error) in
            if (error != nil){
                return
            }
            if placemarks?.count != nil{
                let pm = (placemarks?[0])! as CLPlacemark
                self.displayLocationInfo(placemark: pm)
            }
        }

        let spanX = 0.00725
        let spanY = 0.00725
        locationManager.stopUpdatingLocation()
        let location = locations.last! as CLLocation
        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: spanX, longitudeDelta: spanY))
        self.MapRSR.setRegion(region, animated: true)
        self.MapRSR.delegate = self

        let mapPin = MapPin(name: "", street: "", type: "", postCode: "")
        mapPin.coordinate = center
        mapPin.title = "test"

        self.MapRSR.addAnnotation(mapPin)
    }


    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let pin = mapView.dequeueReusableAnnotationView(withIdentifier: "LocationInfo") ?? AddressView(annotation: annotation, reuseIdentifier: "LocationInfo")
        pin.canShowCallout = true
        return pin
    }

It just won't show my xib view. Does anyone know what I'm doing wrong or how I can achieve the effect I want which is something like this. enter image description here

Ekta Padaliya
  • 5,743
  • 3
  • 39
  • 51
NoSixties
  • 2,443
  • 2
  • 28
  • 65

1 Answers1

3

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

Jeyamahesan
  • 1,101
  • 7
  • 15
  • this part `let calloutViewFrame = customView.frame; customView.frame = CGRect(x: -calloutViewFrame.size.width/2.23, y: -calloutViewFrame.size.height-7, width: 315, height: 200)` makes sure that the view doesn't show. When I take that out it will show but not like it's supposed to obviously – NoSixties Oct 18 '16 at 12:40
  • @NoSixties thats just for setting our custom size of the annotation view, in my case i used that frame sizes for my requirements.in your case set your size whatever you want. – Jeyamahesan Oct 18 '16 at 12:51
  • I know I've tried to set it but it doesn't seem to work for me. – NoSixties Oct 18 '16 at 13:00
  • where does the "test" reuseid come from in your sample application? because when I try to implement it my pin disappears lol – NoSixties Oct 18 '16 at 21:13
  • "reuseId" for reusing the annotation view like reusing of tableview rows, any static id can be used.That id is nothing to do with pin.i don't know how you implemented.Please accept and up vote the answer.Thanks. – Jeyamahesan Oct 19 '16 at 06:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126101/discussion-between-nosixties-and-jeyamahesan). – NoSixties Oct 19 '16 at 10:53