我有一个显示UIImage的UIImageView。
UIImage可能会更改为不同大小的其他UIImage,并且UIImage内部的位置和大小将根据其更改。
我的问题是,我试图添加一个视图,该视图将位于始终更改的UIImage的末尾,但我能够获得的只是UIImageView的框架(始终保持全屏状态)。
如何获取当前显示UIImage的“frame”?
我有一个显示UIImage的UIImageView。
UIImage可能会更改为不同大小的其他UIImage,并且UIImage内部的位置和大小将根据其更改。
我的问题是,我试图添加一个视图,该视图将位于始终更改的UIImage的末尾,但我能够获得的只是UIImageView的框架(始终保持全屏状态)。
如何获取当前显示UIImage的“frame”?
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
}
// 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
}
以下将回答您的问题,假设您的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
,则不需要进行任何计算。 - rmaddyAspectFill
或 ScaleToFill
,那么在这些情况下不需要进行任何计算,因为它们都将填充图像视图。两者之间的区别仅在于缩放方式。前者会缩放图像,直到整个图像视图被填满,并保持纵横比,这意味着图像可能超出框架,而后者将拉伸图像以填充图像视图,而不保持纵横比,因此整个图像将可见。 - Pavanfunc AVMakeRectWithAspectRatioInsideRect(_ aspectRatio: CGSize, _ boundingRect: CGRect) -> CGRect
参数:
aspectRatio:
您想要保持的宽高比(纵横比)。
boundingRect: 您想要适合的边界矩形。
返回值: 返回一个缩放后的CGRect,该CGRect保持由aspectRatio指定的纵横比,并适合于bounding Rect中。
let boundingBox = AVMakeRectWithAspectRatioInsideRect(backgroundImage.size, frame)
基于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...
}
Swift 3.0
虽然有些晚了,但可能对未来的某些人有所帮助。苹果iOS提供了非常简单且内置的解决方案,只需要:
import AVFoundation
let imageRect = AVMakeRect(aspectRatio: image.size, insideRect: self.imageView.bounds)
这样做就可以了。