UIImageView сохраняет соотношение сторон, но соответствует ширине

У меня есть UIImageView с фиксированной шириной и высотой. Я не хочу менять фрейм UIImageView. Я хочу, чтобы он содержал изображение, в котором я сохраняю соотношение сторон, подхожу к ширине и позволяю изображению быть либо слишком высоким, либо слишком коротким для кадра UIImageView. Нравится:

UIImageView frame

Красный - это рамка UIImageView. Серый цвет - это фактическое изображение в том виде, в каком оно отображается.


person SirRupertIII    schedule 23.09.2015    source источник


Ответы (3)


Я думаю, что лучший способ сделать это - поиграть с режимом вашего imageView (Aspect Fill, Aspect Width и т.д.), и это основано на соотношении между шириной и высотой изображения.

if image.width > image.height {
    imageView.contentMode = UIViewContentModeScaleAspectFit
    //since the width > height we may fit it and we'll have bands on top/bottom
} else {
  imageView.contentMode = UIViewContentModeScaleAspectFill
  //width < height we fill it until width is taken up and clipped on top/bottom
}

UIViewContentModeScaleAspectFit

Масштабирует содержимое, чтобы оно соответствовало размеру представления, сохраняя соотношение сторон. Любая оставшаяся часть границ обзора прозрачна.

UIViewContentModeScaleAspectFill

Масштабирует содержимое, чтобы заполнить размер представления. Некоторая часть контента может быть обрезана, чтобы заполнить границы представления.

Я не тестировал это, но это кажется правильным

person Glenn    schedule 23.09.2015
comment
Отлично, я возьмусь с этим. Отличная идея. - person SirRupertIII; 24.09.2015
comment
Я работаю с MPMediaItemArtwork, как это сделать? - person Jared Chu; 02.11.2016
comment
это решение не принимает во внимание форму вида, только форму изображения. это решение работает, только если вид квадратный. для широкого изображения, если вид широкий и тонкий, он будет соответствовать размеру изображения, тогда как он должен быть заполнен. - person Andy; 21.05.2019

Я думаю, вам нужно сравнить соотношение сторон изображения с соотношением сторон самого UIImageView:

private func updateUI() {
    guard let image = image else { return }
    let viewAspectRatio = self.bounds.width / self.bounds.height
    let imageAspectRatio = image.size.width / image.size.height
    if viewAspectRatio > imageAspectRatio {
        self.contentMode = .scaleAspectFill
    } else {
        self.contentMode = .scaleAspectFit
    }
}

override var image: UIImage? { didSet { updateUI() }}

override func layoutSubviews() {
    super.layoutSubviews()
    updateUI()
}

Примечание: это ширина по размеру

person Andy    schedule 21.05.2019
comment
Можно ли использовать это для установки соотношения сторон изображения 16: 9? Если да, то как лучше всего это сделать? - person Luke Irvin; 08.05.2020
comment
Вопрос заключался в сохранении исходного соотношения сторон изображения, но при отображении изображения в представлении, возможно, с другим соотношением сторон, чем изображение. Если вы хотите задать соотношение сторон изображения, вы можете использовать ограничения. Например, в построителе интерфейса вы можете установить соотношение сторон вашего UIImageView. Вы об этом спрашиваете? - person Andy; 10.05.2020

Swift 5.1 iOS 13

Поскольку мой был в ячейке заголовка в представлении коллекции, у меня сработало следующее:

if headerCell!.imageView.frame.width > headerCell!.imageView.frame.height {
    headerCell!.imageView.contentMode = .scaleAspectFit
    //since the width > height we may fit it and we'll have bands on top/bottom
} else {
     headerCell!.imageView.contentMode = .scaleAspectFill
     //width < height we fill it until width is taken up and clipped on top/bottom
}
person Marlhex    schedule 15.11.2019