UIViewContentModeScaleAspectFill not clipping


144

Я пытаюсь нарисовать несколько миниатюр изображений фиксированного размера (100x100), используя UIImageView. Я установил размер кадра моего изображения 100x100 и установил contentModeв UIViewContentModeScaleAspectFill.

Насколько я понимаю, это должно привести к тому, что изображение будет нарисовано в размере, который я установил, и изображение заполнит область изображения, и обрежет любые части изображения, которые не соответствуют размеру, который я установил для вида изображения. Тем не менее, изображение по-прежнему отображается больше или меньше размера, установленного для него размером 100x100.

Если я установил contentModeна UIviewContentModeScaleToFill, то изображение рисуется точно 100х100, но это искажено , чтобы вписаться в эти размеры. Любые идеи, почему заполнение аспекта не обрезается, как ожидалось?

Вот мой код:

_photoView = [[UIImageView alloc] initWithImage:photoImage];
_photoView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_photoView];

CGRect photoFrame = _photoView.frame;
photoFrame.size = CGSizeMake(100, 100);
_photoView.frame = photoFrame;

Чтобы лучше проиллюстрировать, вот скриншот того, что я вижу. Зеленые квадраты - это то, UIViewс чем UIImageViewя работаю. Я установил их фоновый цвет на зеленый, а рамку вида на 100x100. Как тест, они UIImageViewsимеют размеры до 50х50. Как вы можете видеть, при использовании ...AspectFillизображения размеры не 50x50, а в некоторых случаях смещены от того места, где я бы их хотел. При использовании ...ScaleToFillони имеют правильный размер, но изображение искажено.

Снимок экрана, иллюстрирующий проблему

Ответы:


352

Можете ли вы попробовать установить клип на границы

[_photoview setClipsToBounds:YES];

Или прямо в раскадровке / Xib, если вы можете:

введите описание изображения здесь


10
Вот и все - спасибо. (Я добавил скриншот выше, чтобы лучше показать то, что я видел, в качестве примера, если кто-то еще сталкивался с этой проблемой.)
Джош Бюлер

3
В InterfaceBuilder, переименовано (бесполезно) в «Обрезать подпредставления» (примечание: в этом случае оно не обрезает «подпредставления», имя неверное: оно обрезает «САМОЕ И ПОДВИДЫ»)
Адам

3
Отметив опцию «Clip Subviews» в NIB-файле, вы делаете то же самое. Приветствия.
codeburn

Но что делать, если вы хотите добавить тень, используя свойство CALayer :( добавление другого представления позади него не идеально для меня
Rambatino

Если вы используете Auto Layout, как я, есть еще одна возможная причина - NSLayoutConstraint "UIView-Encapsulated-Layout-Height", нарушающий ограничения размера UIImageView.
ewiinnnnn

8

Если вы хотите расширить свои знания, есть действительно хорошая статья о том, как визуализируется стек iOS UIView . Существует также более углубленная статья обо всем конвейере чертежей .

В итоге:

  1. Растеризация - весь контент вида растеризуется (рисуется или закадровый пиксельный буфер) в координатном пространстве границ вида. Это могут быть данные изображения или пользовательский рисунок (то есть drawRect:), но содержимое подпредставления. Эта растеризация учитывает contentModeсвойство.

    Все, что находится за пределами представления, отбрасывается.

  2. Композиция - результаты составляются (рисуются друг на друга) от подпредставления до суперпредставлений. Это использует свойство frame подпредставления.

    Если clipsToBoundsсвойствоYES в суперпредставлении, оно будет отбрасывать содержимое подпредставления за его пределами.


2

была та же проблема, и она была решена, отметив «Клип Subviews».

Изображение показывалось правильно для всех видов (3.5,4,4.7,5.5, ipad) в режиме предварительного просмотра раскадровки, но не в симуляторе.

После того, как я поставил галочку "Клип Subviews", проблема была решена. :)


1

Проверка «Клип подпредставлений» непосредственно в раскадровке / Xib также работала для меня. введите описание изображения здесь


0

Мои подпредставления меняли размеры, и я понял, что это потому, что в xib был установлен автоматический макет: введите описание изображения здесь


0

Если все не получается,

сделать клипы к границам в методе viewDidLayoutSubviews.

Пример :

  override func viewDidLayoutSubviews() {

    imageProfile.layer.cornerRadius = imageProfile.bounds.size.width/2
    imageProfile.clipsToBounds = true
    imageProfile.layer.masksToBounds = true
 }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.