How to change default background color of callout bubble with detailCalloutAccessoryView

夙愿已清 提交于 2019-12-04 10:28:31

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.

UIViewCallout is a private class. If you want custom callout view:

  1. disable standart callout view.canShowCallout = false

  2. implement MKMapViewDelegate methods with your custom UIView for callout:

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        let redCalloutView = RedCalloutView(view.annotation)
        view.addSubview(redCalloutView)
    }
    
    func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
        view.subviews.forEach {
            if $0 is RedCalloutView {
                $0.removeFromSuperview()
            }
        }
    }
    
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    for v in view.subviews{
        if v.subviews.count > 0{
            v.subviews[0].backgroundColor = UIColor.red
        }
    }
}

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    for v in view.subviews{
        if v.subviews.count > 0 {
            let colloutView = v.subviews[0]
            colloutView.backgroundColor = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 0.8)
            if colloutView.subviews.count > 0 {
                if colloutView.subviews[0].subviews.count > 0{
                    colloutView.subviews[0].subviews.forEach { (view) in
                        if let label = view as? UILabel{
                            label.textColor = UIColor.white
                        }
                    }
                }
            }
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!