PvDev
PvDev

Reputation: 829

MKAnnontation pin image resize issue

Custom pin image for MKAnnotation. When tapping or zooming map the custom pin gets stretched and opening for home map car pin marker are big in size. Here is output result which I'm getting in mapview:

enter image description here

Here is the code which I have tried so far:

var pin = MKAnnotationView()
var userPinView: MKAnnotationView!

if annotation is MKUserLocation {

    pin = mapView.view(for: annotation) ?? MKAnnotationView(annotation: annotation, reuseIdentifier: nil)
    let pinImage = UIImage(named: "carIcon3")
    let size = CGSize(width: 38, height: 44)
    UIGraphicsBeginImageContext(size)
    pinImage!.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
    pin.image = resizedImag
    userPinView = pin
    userPinView.contentMode = .scaleAspectFill
    userPinView.clipsToBounds = true
    return pin
}

if !(annotation is MKPointAnnotation) {
    return nil
}

let annotationIdentifier = "AnnotationIdentifier"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier)

if annotationView == nil {
    annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
    //            annotationView!.canShowCallout = true
} else {
    annotationView!.annotation = annotation
}
return annotationView

How to get result like this:

enter image description here

Tried to user current location marker. But it crashing

   func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {

        UIView.animate(withDuration: 0.005) {

        let angle = newHeading.trueHeading.toRadians() // convert from degrees to radians

        self.userPinView.transform = CGAffineTransform(rotationAngle: CGFloat(angle)) // rotate the picture
    }
}

here the code which i have performing didselect and deselect for location annotation.

     func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {

    if annotView == true {

        let heights = 70

        let widths = 50

        UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveLinear, animations: {

            view.frame.size = CGSize(width: widths, height: heights)

        })
    }

}

func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {

    let heights = 70

    let widths = 50

    UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveLinear, animations: {

        view.frame.size = CGSize(width: view.frame.width - CGFloat(widths), height: view.frame.height - CGFloat(heights))

    })
}

Upvotes: 1

Views: 1408

Answers (1)

AamirR
AamirR

Reputation: 12198

Though I cannot reproduce the issue, but recommend couple of changes:

  1. separate the view configuration logic, lets subclass MKAnnotationView, like so:

    class CarAnnotationView: MKAnnotationView {
        override var annotation: MKAnnotation? {
            didSet {
                let size = CGSize(width: 38, height: 44)
                UIGraphicsBeginImageContext(size)
                UIImage(named: "carIcon")?.draw(in: CGRect(origin: .zero, size: size))
                self.image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
            }
        }
    }
    
  2. change within mapView(_:viewFor:) to take advantage of the reusable view, like so:

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            userPinView = mapView.dequeueReusableAnnotationView(withIdentifier: "carId") as? CarAnnotationView
            if (userPinView == nil) {
                userPinView = CarAnnotationView(annotation: nil, reuseIdentifier: "carId")
            }
    
            userPinView.annotation = annotation
            userPinView.setNeedsLayout()
            // userPinView.centerOffset = CGPoint(x: 0, y: -view.bounds.midY)
    
            return userPinView
        }
    
        guard annotation is MKPointAnnotation else { return nil }
    
        let annotationIdentifier = "AnnotationIdentifier"
        ...
        return annotationView
    
    }
    
  3. delete unnecessary variable

    var pin = MKAnnotationView()
    

Upvotes: 3

Related Questions