UIImageView получает позицию показа изображения
У меня есть UIImageView, который показывает UIImage.
UIImage может измениться на другой UIImage разного размера, а положение и размер UIImage внутри изменятся в соответствии с ним.
Моя проблема в том, что я пытаюсь добавить представление, которое будет в конце UIImage (которое меняет все время), и все, что я могу получить, это кадр UIImageView (который постоянно остается на весь экран).
Как я могу получить "фрейм" текущего отображения UIImage?
Ответы
Ответ 1
Следующее ответит на ваш вопрос, предполагая, что ваш 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);
}
Для лучшей иллюстрации различий между тремя режимами содержимого см. ниже:
![enter image description here]()
Ответ 2
Swift 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
}
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
}
Для Swift <3.0
Вот вышеупомянутый метод в 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
Я рекомендую использовать встроенную функцию AVMakeRectWithAspectRatio.
func AVMakeRectWithAspectRatioInsideRect(_ aspectRatio: CGSize, _ boundingRect: CGRect) -> CGRect
Параметры:
AspectRatio:
Отношение ширины и высоты (соотношение сторон), которое вы хотите сохранить.
boundingRect: Ограничивающий прямоугольник, в который вы хотите поместиться.
Возвращаемое значение
Возвращает масштабированный CGRect, который поддерживает соотношение сторон, указанное aspectRatio, которое находится в пределах ограничивающего Rect.
let 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)