You need to:
- calculate the aspectRatio for aspectFill
- multiply the x,y coords for your annotation by the aspectRatio
- adjust that point by the amount of the image that extends outside the view frame
This is one way to do it (a little verbose, for clarity):
func aspectFillPoint(for point: CGPoint, in view: UIImageView) -> CGPoint {
guard let img = view.image else {
return CGPoint.zero
}
// imgSize will be modified
var imgSize = img.size
let viewSize = view.frame.size
let aspectWidth = viewSize.width / imgSize.width
let aspectHeight = viewSize.height / imgSize.height
// calculate aspectFill ratio
let f = max(aspectWidth, aspectHeight)
// scale imgSize
imgSize.width *= f
imgSize.height *= f
// unless aspect ratio of view is the same as image,
// it will either extend above and below or left and right
// of the view frame
let xOffset = (viewSize.width - imgSize.width) / 2.0
let yOffset = (viewSize.height - imgSize.height) / 2.0
// scale the original point, and adjust for offsets
return CGPoint(
x: (point.x * f) + xOffset,
y: (point.y * f) + yOffset
)
}
Assuming you have an image assigned to theImageView
, which is set to .scaleAspectFill
, you can call it like this:
let annotationPoint = CGPoint(x: 232, y: 148)
var newPoint = aspectFillPoint(for: annotationPoint, in: theImageView)
// Note: newPoint is relative to the View Bounds, so unless the
// imageView is at 0,0 we need to adjust for position
newPoint.x += theImageView.frame.origin.x
newPoint.y += theImageView.frame.origin.y