Search code examples
swiftmkmapviewmkannotationswift3mkannotationview

How to change default background color of callout bubble with detailCalloutAccessoryView


In my app I have the following sutuation.

I've implemented a custom callout bubble with custom detailCalloutAccessoryView with two labels inside.

I know how to change the color of detailCalloutAccessoryView with this line.

view.detailCalloutAccessoryView?.backgroundColor = UIColor.red

But I can't figure out how to change background color of the main bubble (it is transparent grey/white now). With view.detailCalloutAccessoryView?.backgroundColor = UIColor.red line my calloutbubble looks like this:

enter image description here

But I want my custom bubble to look like this:

enter image description here

Here is my viewFor annotation method:

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

        if annotation is MKUserLocation {
            return nil
        }

        let identifier = "pin"
        var view : MKAnnotationView

        if let dequedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
            dequedView.annotation = annotation

            view = dequedView

        } else {
            view = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)

            view.canShowCallout = true

        }

             let pinImage = UIImage.init(named: "customPin")


        DispatchQueue.main.async(execute: {

            view.detailCalloutAccessoryView?.backgroundColor = UIColor.red

        })

        view.image = pinImage

        configureDetailView(annotationView: view)
        return view
    }

I'm working in Xcode 8 w/ Swift 3.

It would be also interesting to know how to change font type and default black color of the title from black to another color. In detail view i can easily change color of my custom labels in xib file but don't know how to access default title properties.


Solution

  • I had created the code for your requirement please find the below url for download the code and review it.

    Link : https://www.dropbox.com/s/o2howwqceq8rsgu/MapInformation.zip?dl=0

    Environment : Xcode 8 and Swift3

    Highlight the code which I had done it.

    I had taken the approach to display the Popup(UIPresentationController) instead of callout. For more information please find the below code.

    A) I had used the UIButton to display as annotation on the MapView and display the popup when user click on it.

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
            if annotation is MKUserLocation {
                return nil
            }
    
            let identifier = "pin"
            var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as! AnnotationView?
    
            if annotationView == nil {
    
                annotationView = AnnotationView(annotation: annotation, reuseIdentifier: identifier)
                annotationView?.canShowCallout = false
            }
    
            else {
                annotationView?.annotation = annotation
            }
    
            //Take the UIButton and implement the touchupinside action for showing the popup.
            let pinImage = UIImage.init(named: "customPin")
            annotationView?.frame = CGRect(x: 0, y: 0, width: (pinImage?.size.width)!, height: (pinImage?.size.width)!)
            annotationView?.mapPin = UIButton(frame: (annotationView?.frame)!);
            annotationView?.mapPin.addTarget(self, action: #selector(ViewController.showPopup(sender:)), for: .touchUpInside)
    
            annotationView?.addSubview((annotationView?.mapPin)!)
            annotationView?.mapPin.setImage(pinImage, for: .normal)
    
            return annotationView
        }
    

    B) Display the popup when user click on the annotation.

    func showPopup(sender: UIButton!) {
    
            let popupVC = self.storyboard?.instantiateViewController(withIdentifier: "Popup") as? Popup
            popupVC?.preferredContentSize = CGSize(width: 250, height: 150)
            popupVC?.modalPresentationStyle = UIModalPresentationStyle.popover
    
            let rect = sender.superview?.convert(sender.frame, to: self.view)
            popupVC?.popoverPresentationController?.delegate = self;
            popupVC?.popoverPresentationController?.sourceView = self.view
            popupVC?.popoverPresentationController?.sourceRect = rect!
            popupVC?.popoverPresentationController?.backgroundColor = UIColor.red
    
            self.present(popupVC!, animated: true, completion: nil)
        }
    

    Note

    If you want to change the popup color from red to other different color then you can do only single line of coding by changing the color name.

    popupVC?.popoverPresentationController?.backgroundColor = UIColor.red

    Please look into the below screenshot.

    enter image description here