iOS - Swift - Clickable Regions on a UIImage

3628 views ios
4

I am working on a project where I have to plot points in specific regions on an image that represents the human body. In Interface Builder, I have set up a container UIView, which takes up most of the vertical center of the main view. In that container view, I placed a UIImageView and set the graphic in IB. The graphic is much larger than both the UIImageView and the container UIView, more specifically, it’s taller. The ContentMode of the UIImageView is set to AspectFit because I want the image to not show as bigger than the container.

The code creates several CGRect instances which are regions where user taps mean something. When the user taps on the container view, code is used to determine if the point is within one of the regions and if it is, a dot is drawn in the center of that region.

The problem is that when I run the app on certain simulators, the region rectangles are not in the right place on the image. For example, when I run the app on an iPhone X, the rectangle region that is in place for the head looks fine. When I run the app on an iPhone XR, the rectangle region is off to the left of the head.

enter image description here enter image description here

I am using coordinates to define the region rectangles that are based on where, for example, the human head is in the image. I feel like this is not the right way to do this since AspectFit for the ContentMode of the image is most likely causing the image to be scaled to maintain aspect.

Bottom line is that I want a rectangle to be in the right place and size no matter how the image scales. No sure if how I am doing it makes sense, so hope that some suggestions come in that offer a better way to do this.

answered question

1 Answer

10

You just need to do some maths.

On the original image, identify the region the user can tap. Note down its x, y, w, h, relative to the image.

Figure out how much the image shrank in the image view. Since you said the image is taller than the image view, the image underwent a scale factor of imageViewHeight / imageHeight. We'll now refer to this as scaleFactor.

The region's Y coordinate must have also gone down by scaleFactor, so you multiply regionY by scaleFactor to get newY.

The region's width and height will do the same thing, so multiply them by scaleFactor and get newWidth and newHeight.

The X coordinate of the region, relative to the image view, is a bit tricky. You need to account for the amount of empty space that the image view has created by scaling down the image. This emptySpace is calculated by (imageViewWidth - newWidth) / 2. Then to calculate the new region's X coordinate relative to the image view, you do emptySpace + X * scaleFactor.

Now the rect (newX, newY, newWidth, newHeight) is the region relative to the image view that the user can tap!

posted this

Have an answer?

JD

Please login first before posting an answer.