UIImageView获取显示图像的位置

时间:2022-09-10 20:33:39

I have a UIImageView which shows an UIImage.

我有一个显示UIImage的UIImageView。

The UIImage may change to other UIImage in different size, and the position and the size of the UIImage inside will change according according to it.

UIImage可能会改变为不同大小的其他UIImage,内部UIImage的位置和大小会根据它而改变。

My Problem is that i'm trying add a view that will be at the end of the UIImage (which change all the time) and all I can get is the frame of the UIImageView (which stay full screen all the time).

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

How can i get the "frame" of current showing UIImage ?

我怎样才能获得当前显示UIImage的“框架”?

5 个解决方案

#1


18  

The following will answer your question, assuming your UIImageView used UIViewContentModeAspectFit:

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

You have to regard the image sizing of the image inside UIImageView. This depends on how you set the contentMode. According your description, I assume you are using UIViewContentModeAspectFit. The resulting image will also be centered in the UIImageView so you also have to consider this for the calculation.

您必须考虑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);
}

For a better illustration of the differences between the three content modes, see below:

有关三种内容模式之间差异的更好说明,请参阅以下内容:

UIImageView获取显示图像的位置

#2


10  

For Swift 3.0

对于Swift 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
}

For Swift < 3.0

对于Swift <3.0

Here is the above method in Swift. Again, assuming that contentMode is set to .ScaleAspectFit If there is no image on the given imageView CGRectZero will be returned.

这是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
}

#3


4  

I recommend using built in function AVMakeRectWithAspectRatio.

我建议使用内置函数AVMakeRectWithAspectRatio。

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

Parameters:

参数:

aspectRatio:
The width and height ratio (aspect ratio) you want to maintain.

aspectRatio:要维护的宽高比(宽高比)。

boundingRect: The bounding rectangle you want to fit into.

boundingRect:您想要适合的边界矩形。

Return Value Returns a scaled CGRect that maintains the aspect ratio specified by aspectRatio that fits within bounding Rect.

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

let boundingBox = AVMakeRectWithAspectRatioInsideRect(backgroundImage.size, frame)

let boundingBox = AVMakeRectWithAspectRatioInsideRect(backgroundImage.size,frame)

#4


1  

Based on the wonderfully simple solution from Janusz, here's what I did:

基于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


0  

Swift 3.0

Swift 3.0

I know its quite late but might help someone in future. Its very simple and inbuilt solution provided by iOS. Just need to:

我知道它已经很晚了但未来可能会对某人有所帮助。 iOS提供的非常简单和内置的解决方案。只需要:

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

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

#1


18  

The following will answer your question, assuming your UIImageView used UIViewContentModeAspectFit:

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

You have to regard the image sizing of the image inside UIImageView. This depends on how you set the contentMode. According your description, I assume you are using UIViewContentModeAspectFit. The resulting image will also be centered in the UIImageView so you also have to consider this for the calculation.

您必须考虑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);
}

For a better illustration of the differences between the three content modes, see below:

有关三种内容模式之间差异的更好说明,请参阅以下内容:

UIImageView获取显示图像的位置

#2


10  

For Swift 3.0

对于Swift 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
}

For Swift < 3.0

对于Swift <3.0

Here is the above method in Swift. Again, assuming that contentMode is set to .ScaleAspectFit If there is no image on the given imageView CGRectZero will be returned.

这是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
}

#3


4  

I recommend using built in function AVMakeRectWithAspectRatio.

我建议使用内置函数AVMakeRectWithAspectRatio。

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

Parameters:

参数:

aspectRatio:
The width and height ratio (aspect ratio) you want to maintain.

aspectRatio:要维护的宽高比(宽高比)。

boundingRect: The bounding rectangle you want to fit into.

boundingRect:您想要适合的边界矩形。

Return Value Returns a scaled CGRect that maintains the aspect ratio specified by aspectRatio that fits within bounding Rect.

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

let boundingBox = AVMakeRectWithAspectRatioInsideRect(backgroundImage.size, frame)

let boundingBox = AVMakeRectWithAspectRatioInsideRect(backgroundImage.size,frame)

#4


1  

Based on the wonderfully simple solution from Janusz, here's what I did:

基于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


0  

Swift 3.0

Swift 3.0

I know its quite late but might help someone in future. Its very simple and inbuilt solution provided by iOS. Just need to:

我知道它已经很晚了但未来可能会对某人有所帮助。 iOS提供的非常简单和内置的解决方案。只需要:

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

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