【问题标题】:UIImageView get the position of the showing ImageUIImageView 获取显示图像的位置
【发布时间】:2014-10-13 20:55:33
【问题描述】:

我有一个显示 UIImage 的 UIImageView。

UIImage可能会变成其他不同大小的UIImage,里面的UIImage的位置和大小也会随之改变。

我的问题是我正在尝试添加一个位于 UIImage 末尾的视图(它一直在变化),而我所能得到的只是 UIImageView 的框架(它一直保持全屏) .

如何获取当前显示 UIImage 的“框架”?

【问题讨论】:

  • 没有直接的 API 可以获取该信息。您需要根据图像视图的框架、图像大小和图像视图的contentMode 自行计算。
  • @rmaddy 这听起来很难说。没有办法以更简单的方式破解它吗?
  • 您可以使用 Imageview.image.size.width/height 来获取宽度和高度。虽然我不知道 origin.x 和 y 属性
  • 让我们以这种方式开始,请发布您的代码,展示如何将图像加载到图像视图

标签: ios objective-c uiimageview uiimage


【解决方案1】:

斯威夫特 4.2 & 5.0

func calculateRectOfImageInImageView(imageView: UIImageView) -> CGRect {
        let imageViewSize = imageView.frame.size
        let imgSize = imageView.image?.size

        guard let imageSize = imgSize else {
            return CGRect.zero
        }

        let scaleWidth = imageViewSize.width / imageSize.width
        let scaleHeight = imageViewSize.height / imageSize.height
        let aspect = fmin(scaleWidth, scaleHeight)

        var imageRect = CGRect(x: 0, y: 0, width: imageSize.width * aspect, height: imageSize.height * aspect)
        // Center image
        imageRect.origin.x = (imageViewSize.width - imageRect.size.width) / 2
        imageRect.origin.y = (imageViewSize.height - imageRect.size.height) / 2

        // Add imageView offset
        imageRect.origin.x += imageView.frame.origin.x
        imageRect.origin.y += imageView.frame.origin.y

        return imageRect
    }

斯威夫特 3.0

// MARK: - Create Rect
func calculateRectOfImageInImageView(imageView: UIImageView) -> CGRect {
    let imageViewSize = imageView.frame.size
    let imgSize = imageView.image?.size

    guard let imageSize = imgSize, imgSize != nil else {
        return CGRect.zero
    }

    let scaleWidth = imageViewSize.width / imageSize.width
    let scaleHeight = imageViewSize.height / imageSize.height
    let aspect = fmin(scaleWidth, scaleHeight)

    var imageRect = CGRect(x: 0, y: 0, width: imageSize.width * aspect, height: imageSize.height * aspect)
    // Center image
    imageRect.origin.x = (imageViewSize.width - imageRect.size.width) / 2
    imageRect.origin.y = (imageViewSize.height - imageRect.size.height) / 2

    // Add imageView offset
    imageRect.origin.x += imageView.frame.origin.x
    imageRect.origin.y += imageView.frame.origin.y

    return imageRect
}

对于斯威夫特

这是 Swift 中的上述方法。同样,假设contentMode 设置为.ScaleAspectFit 如果给定imageView 上没有图像,则将返回CGRectZero

func calculateRectOfImageInImageView(imageView: UIImageView) -> CGRect {
    let imageViewSize = imageView.frame.size
    let imgSize = imageView.image?.size

    guard let imageSize = imgSize where imgSize != nil else {
        return CGRectZero
    }

    let scaleWidth = imageViewSize.width / imageSize.width
    let scaleHeight = imageViewSize.height / imageSize.height
    let aspect = fmin(scaleWidth, scaleHeight)

    var imageRect = CGRect(x: 0, y: 0, width: imageSize.width * aspect, height: imageSize.height * aspect)
    // Center image 
    imageRect.origin.x = (imageViewSize.width - imageRect.size.width) / 2
    imageRect.origin.y = (imageViewSize.height - imageRect.size.height) / 2

    // Add imageView offset
    imageRect.origin.x += imageView.frame.origin.x
    imageRect.origin.y += imageView.frame.origin.y

    return imageRect
}

【讨论】:

  • 如何使用它只截取屏幕上的图像?
【解决方案2】:

假设您的 UIImageView 使用了 UIViewContentModeAspectFit,以下内容将回答您的问题:

你必须考虑 UIImageView 中图像的图像大小。这取决于您如何设置 contentMode。根据您的描述,我假设您使用的是 UIViewContentModeAspectFit。生成的图像也将在 UIImageView 中居中,因此您还必须在计算时考虑这一点。

-(CGRect )calculateClientRectOfImageInUIImageView:(UIImageView *)imgView
{
    CGSize imgViewSize=imgView.frame.size;                  // Size of UIImageView
    CGSize imgSize=imgView.image.size;                      // Size of the image, currently displayed

    // Calculate the aspect, assuming imgView.contentMode==UIViewContentModeScaleAspectFit

    CGFloat scaleW = imgViewSize.width / imgSize.width;
    CGFloat scaleH = imgViewSize.height / imgSize.height;
    CGFloat aspect=fmin(scaleW, scaleH);

    CGRect imageRect={ {0,0} , { imgSize.width*=aspect, imgSize.height*=aspect } };

    // Note: the above is the same as :
    // CGRect imageRect=CGRectMake(0,0,imgSize.width*=aspect,imgSize.height*=aspect) I just like this notation better

    // Center image

    imageRect.origin.x=(imgViewSize.width-imageRect.size.width)/2;
    imageRect.origin.y=(imgViewSize.height-imageRect.size.height)/2;

    // Add imageView offset

    imageRect.origin.x+=imgView.frame.origin.x;
    imageRect.origin.y+=imgView.frame.origin.y;

    return(imageRect);
}

为了更好地说明三种内容模式之间的差异,请参见下文:

【讨论】:

  • 这个解决方案不是假设UIViewContentModeScaleAspectFit 而不是UIViewContentModeScaleAspectFill?如果您使用UIViewContentModeScaleAspectFill,则无需计算。
  • 谢谢,是的,当然是 ..AspectFit。但是,如果需要 ...AslectFill,您还需要进行一些计算,因为图像可能会在顶部或左侧被裁剪,以防它不适合 UIImageView 而无需更改 with/height 比率。这就是 ...AspectFill 和 ...ScaleToFill 之间的区别。
  • @Marcus 我不确定我是否理解您的评论。如果您使用AspectFillScaleToFill,则在这些情况下不需要计算,因为它们都会填充图像视图。两者之间的区别仅在于它的扩展方式。前者缩放图像直到整个图像视图被填充,同时保持纵横比,这意味着图像可以超出框架,而后者将拉伸图像以填充图像视图而不保持纵横比,因此整个图像将可见。
  • 也许我正在考虑在图像视图中返回图像可见部分的矩形。
【解决方案3】:

我建议使用内置函数 AVMakeRectWithAspectRatio。

func AVMakeRectWithAspectRatioInsideRect(_ aspectRatio: CGSize, _ boundingRect: CGRect) -> CGRect

参数:

纵横比:
您要保持的宽高比(纵横比)。

boundingRect: 您要适应的边界矩形。

返回值 返回一个缩放的 CGRect,它保持 aspectRatio 指定的宽高比,适合边界 Rect。

让 boundingBox = AVMakeRectWithAspectRatioInsideRect(backgroundImage.size, frame)

【讨论】:

    【解决方案4】:

    基于 Janusz 非常简单的解决方案,我做了以下工作:

    let visibleRect = AVMakeRect(aspectRatio: CGSize(width: image.size.width, height: image.size.height), insideRect: self.frame)
    if visibleRect.contains(point) {
        // Do something great here...
    }
    

    【讨论】:

      【解决方案5】:

      Swift 3.0

      我知道它很晚,但将来可能会帮助某人。它由 iOS 提供的非常简单和内置的解决方案。只需要:

      import AVFoundation
      let imageRect = AVMakeRect(aspectRatio: image.size, insideRect: self.imageView.bounds)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多