2

我正在做一个项目,我必须在代表人体的图像上的特定区域中绘制点。在Interface Builder中,我设置了一个容器UIView,它占据了主视图的大部分垂直中心。在那个容器视图中,我放置了一个 UIImageView 并在 IB 中设置了图形。图形比 UIImageView 和容器 UIView 都大得多,更具体地说,它更高。UIImageView 的 ContentMode 设置为 AspectFit,因为我希望图像不显示为大于容器。

该代码创建了几个 CGRect 实例,这些实例是用户点击有意义的区域。当用户点击容器视图时,代码用于确定该点是否在某个区域内,如果是,则在该区域的中心绘制一个点。

问题是当我在某些模拟器上运行应用程序时,区域矩形不在图像上的正确位置。例如,当我在 iPhone X 上运行应用程序时,头部的矩形区域看起来不错。当我在 iPhone XR 上运行应用程序时,矩形区域位于头部左侧。

在此处输入图像描述 在此处输入图像描述

我正在使用坐标来定义区域矩形,这些矩形基于例如人头在图像中的位置。我觉得这不是正确的方法,因为图像的 ContentMode 的 AspectFit 很可能导致图像被缩放以保持纵横比。

底线是,无论图像如何缩放,我都希望矩形位于正确的位置和大小。不确定我的做法是否有意义,所以希望有一些建议可以提供更好的方法来做到这一点。

更新 1:UIImageView 固定在周围的 UIView 上,因此它的宽度和高度与容器一样大。由于图像比 UIImageView 更瘦,图像显示在它的中心。在附加的图像中,紫色背景是 UIImageView 显示最上面的 UIView 的背景颜色。

更新 2:我检查了宽度和高度的比例,发现它们不同。宽度比例因子为 1.36565656565,高度比例因子为 2.104。我尝试了使用 Sweeper 给出的两个比例因子给出的公式,但没有运气。

4

3 回答 3

1

你只需要做一些数学。

在原始图像上,确定用户可以点击的区域。记下它相对于图像的 x、y、w、h。

弄清楚图像在图像视图中缩小了多少。由于您说图像比图像视图高,因此图像的比例因子为imageViewHeight / imageHeight. 我们现在将其称为scaleFactor.

该区域的 Y 坐标一定也下降了scaleFactor,所以regionY乘以scaleFactor得到newY

该区域的宽度和高度将做同样的事情,因此将它们乘以scaleFactor并得到newWidthnewHeight

区域的 X 坐标,相对于图像视图,有点棘手。您需要通过缩小图像来考虑图像视图创建的空白空间量。这emptySpace是由 计算的(imageViewWidth - newWidth) / 2。然后要计算新区域相对于图像视图的 X 坐标,您可以执行emptySpace + X * scaleFactor.

现在矩形(newX, newY, newWidth, newHeight)是用户可以点击的相对于图像视图的区域!

于 2018-11-03T19:57:16.663 回答
0

我为每个设备上的位置完全相同的矩形制作了这段代码。为了检查它是否是斧头电话,我在 viewDidLoad 中执行并将约束设置为我想要的并添加标签栏大小。

@IBOutlet weak var tabMenu:          NSLayoutConstraint!
@IBOutlet weak var topConstraint:    NSLayoutConstraint!
@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

@IBOutlet weak var backgroundImg: UIImageView!
@IBOutlet weak var rectangleImg:  UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Check if it's a iPhone X
    if #available(iOS 11, *) {
        let safeArea = UIApplication.shared.delegate?.window??.safeAreaInsets

        // If its a x phone i use safe instead of superView
        guard let safe = safeArea else { return }
        if safe.bottom > 0 {
            topConstraint.constant = safe.top
            bottomConstraint.constant = safe.bottom + tabMenu.constant
        }
    }
}

override func viewDidAppear(_ animated: Bool) {

    // Here I set the rectangle to 36% of the width and height (change to what you want)
    rectangleImg.frame = CGRect(x: 0, y: 0, width: backgroundImg.frame.width * 0.36,
    height: backgroundImg.frame.height * 0.36)

    // Last I put the rectangle in the center of background image
    rectangleImg.center.x = backgroundImg.center.x
    rectangleImg.center.y  = backgroundImg.center.y

}

希望这段代码能有所帮助!

于 2018-11-03T20:07:09.777 回答
0

我的问题的根源是我将 UIImageView 的四个侧面固定在其容器视图上。当设备的宽度发生变化时,它会正确缩放图像,但会导致图形被“拉伸”。例如,这导致头部的宽度增加。我现在已经通过锁定图像的宽度解决了这个问题,因此无论使用什么设备,我从原始图像中得出的坐标都保持不变。

对于那些阅读本文的人来说,这听起来可能不是一个很好的解决方案,但我必须接受这个,因为我的截止日期非常紧迫。我已经在多个设备模拟器上对其进行了测试,并且可以正常工作。我将来可能不得不重新审视这个,但现在,它正在工作。

我还使用这个问题的答案来修改代码:create a clickable body diagram

于 2018-11-06T12:39:26.777 回答