2016-10-19 4 views
1

Я пытаюсь разместить UIImageView в центре родительского представления. Изображение должно сохранять исходное соотношение сторон, а также не должно превышать границы родителя. Таким образом, пейзажные изображения должны быть ограничены шириной родителя, а портретные изображения должны занимать столько вертикального пространства, сколько необходимо, сохраняя исходное соотношение.AutoLayout: UIImageView и Aspect Fit content mode

Звучит как простая задача для AutoLayout, не так ли? Вот мои настройки для UIImageView:

  • центр вертикально в родителю
  • центр по горизонтали родителя
  • imageView.width < = superview.width
  • imageView.height < = superview.height

Я также установил contentMode в Aspect Fit. Все работает отлично для небольших изображений, которые меньше экрана устройства, но по какой-то причине мой UIImageView занимает больше места, чем его базовый UIImage для больших изображений (обратите внимание на зеленый фон - imageView.backgroundColor = [UIColor greenColor]).

enter image description here

Почему это происходит? Я не эксперт по AutoLayout, мои ограничения выглядят разумными для меня. Если я использую более мелкие изображения, например, 200x400, то UIImageView занимает ровно 200x400 точек на экране без дополнительных зеленых зон.

Я хотел бы добавить границы и закругленные углы, которые, очевидно, не будут работать должным образом в этом случае.

ответ

1

Это происходит потому, что вы установили ограничения ширины и высоты как < =. Для небольших изображений рамка imageView вычисляется без каких-либо проблем, и все ограничения выполняются. Но когда установлено большое изображение, размер imageView будет установлен таким образом, чтобы изображение соответствовало, но в то же время оно ограничено размером супервизора (размер экрана).

  • Если вы знаете, соотношение сторон наверняка, вы можете установить его в качестве сдерживающего и вы не увидите зеленый фон.
  • В противном случае просто оставьте свои ограничения , как они есть, и установите цвет фона для очистки цвета. Этот способ может быть прозрачным, если любые незанятые зоны будут прозрачными, и любое настроенное вами изображение займет максимальное пространство, по крайней мере, в одном измерении.

Edit:

Вероятно, не самое лучшее решение, вид Oldschool.Вы можете добавить жесткие ширину и высоту ограничений и рассчитать их вручную с использованием образа в AspectRatio:

@IBOutlet weak var heightConstraint: NSLayoutConstraint! 
@IBOutlet weak var widthConstraint: NSLayoutConstraint! 

func setImage(image: UIImage) { 
    imageView.image = image 
    let screenSize = UIScreen.main.bounds.size 

    let imageAspectRatio = image.size.width/image.size.height 
    let screenAspectRatio = screenSize.width/screenSize.height 

    if imageAspectRatio > screenAspectRatio { 
     widthConstraint.constant = min(image.size.width, screenSize.width) 
     heightConstraint.constant = widthConstraint.constant/imageAspectRatio 
    } 
    else { 
     heightConstraint.constant = min(image.size.height, screenSize.height) 
     widthConstraint.constant = heightConstraint.constant * imageAspectRatio 
    } 
    view.layoutIfNeeded() 
} 
+0

Я не знаю, соотношение форматов заранее, к сожалению, поскольку мне нужно показать разные изображения в этом представлении: большой, маленький, пейзаж, портрет или даже квадрат. Изображение со скриншота имеет разрешение 3264x2448, и на самом деле оно масштабируется должным образом: оно сохраняет свое соотношение, оно не усекается или не ухудшается. Но, к сожалению, изображение имеет больше физического пространства, чем само изображение. Зеленый фон был добавлен только для целей тестирования. Прозрачный фон не будет работать, так как мне нужно добавить закругленные углы, но эти углы не будут видны, так как края изображения не синхронизируются с изображением. – fraggjkee

+0

Но я думаю, что я могу попытаться добавить соответствующее ограничение отношения к формату программно, хотя ... Звучит как план :) Но на самом деле я могу рассчитать и установить все программно без AutoLayout, поэтому идея этого вопроса заключалась в том, чтобы понять, достижимо ли это без написания кода Swift/Objective-C. – fraggjkee

+0

@fraggjkee: Хорошо, но если ваш план выходит из строя, просто используйте мою функцию из обновленного ответа. Я тестировал его с большими и маленькими, портретными и пейзажными изображениями, похоже, работает так, как ожидалось. – alexburtnik

0

Попытка проверить «Клип к Bounds» для ImageView в Interface Builder Clip to Bounds Image View

, и вы должны быть хорошо -определенная высота и ширина, а не «< =«