UIButton не слушает настройку режима контента?

firstButton — это UIButton типа Custom. Я программно помещаю три из них в каждую ячейку таблицы, таким образом:

[firstButton setImage:markImage forState:UIControlStateNormal];
[firstButton setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:firstButton];

В другом месте я сообщаю об этом clipToBounds. То, что я получаю, - это обрезка центрального квадрата изображения, а не его рендеринг с масштабированием сторон. Я пробовал это множеством способов, включая установку свойства режима в firstButton.imageView, что также не работает.


person Dan Ray    schedule 01.06.2010    source источник
comment
См. решение Криса Нолета ниже: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;   -  person Matt    schedule 10.09.2013
comment
См. stackoverflow.com/a/28205566/481207, в котором показано, что для UIViewContentModeScaleAspectFit требуется установка как contentVerticalAlignment, так и contentHorizontalAlignment.   -  person Matt    schedule 29.01.2015


Ответы (16)


У меня такая же проблема. Я вижу, что этот вопрос немного устарел, но я хочу дать четкий и правильный ответ, чтобы избавить других людей (таких как я) от времени, когда он появляется в их результатах поиска.

Мне потребовалось немного поиска и экспериментов, но я нашел решение. Просто установите ContentMode «скрытого» ImageView, который находится внутри UIButton.

[[firstButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[firstButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

Возможно, это то, на что Дэн Рэй намекал в своем принятом ответе, но я подозреваю, что нет.

person Dave    schedule 19.07.2010
comment
Нет, не было. Решение, на котором я остановился, состояло в том, чтобы использовать UIImageView для хранения изображения, а затем четкий, прозрачный UIButton пользовательского типа поверх него. - person Dan Ray; 19.07.2010
comment
Дэйв, по крайней мере на iOS 3.2 ваше решение мне не подходит. Жаль, потому что я надеялся получить выделение изображения по клику бесплатно. Я даже убедился, что button.imageView не был нулевым, когда я устанавливал contentMode, и устанавливал изображение после установки contentMode, как вы делаете. - person Jacques; 23.08.2010
comment
Просто чтобы уточнить, не работает означает, что изображение отображается в полном разрешении, а не уменьшено, как я надеялся. - person Jacques; 23.08.2010
comment
Жак, вышеизложенное работает для меня в iOS 4.x. К сожалению, я могу воспроизвести проблему с изменением размера при сборке с целью v3.2. Я попытался изменить размер кадра представления UIButton, но это тоже не помогло. фу. - person Dave; 23.09.2010
comment
См. решение Криса Нолета ниже: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; - person Matt; 10.09.2013
comment
попробуйте как UIViewContentModeScaleAspectFill, так и UIViewContentModeScaleAspectFit. «Заливка» расширит ваше изображение, а «Подогнать для меня» — это фиксированный маленький размер. UIViewContentModeScaleAspectFill решит мою проблему. Я хочу увеличить изображение для кнопки - person Wingzero; 27.02.2015
comment
Режимы заполнения контента ТАКЖЕ должны быть установлены, а тип кнопки должен быть настраиваемым. См. этот ответ: stackoverflow.com/a/28205566/3324388 - person Aggressor; 03.03.2015
comment
Мне нравится этот ответ. В течение многих лет я все время забываю об этом и возвращаюсь к нему. - person Şafak Gezer; 14.04.2015
comment
Не будет работать в Swift, потому что скрытый .imageView недоступен. - person Chris Harrison; 22.06.2015
comment
Убедитесь, что ваш UIButton относится к типу .Custom! - person Quantaliinuxite; 05.04.2016

Если вы имеете дело с изображением UIButton (в отличие от его backgroundImage), установка contentMode на самом UIButton или на его imageView не имеет никакого эффекта (несмотря на то, что говорят другие ответы).

Вместо этого сделайте это:

self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
self.button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

Или размер вашего изображения соответственно.

ИЛИ просто используйте UIImageView (который правильно соблюдает contentMode) с прикрепленным к нему UITapGestureRecognizer или прозрачным UIButton поверх него.

person Alfie Hanssen    schedule 04.03.2014
comment
Это работает для моего случая в iOS 7, тогда как все остальные здесь не работают. - person Byte; 07.04.2014
comment
Установка contentHorizontalAlignment и contentVerticalAlignment является правильным решением. Объяснение см. на stackoverflow.com/a/28205566/481207. - person Matt; 29.01.2015
comment
Это ответ, который я искал. - person ninjaneer; 04.12.2015
comment
Этот ответ неверен. Вам делает нужно установить contentMode на imageView, если вы хотите выполнить какое-либо заполнение или подгонку аспекта, как разъяснили другие ответы. См.: stackoverflow.com/a/7944316/746890. - person Chris Nolet; 02.02.2018

Вместо того, чтобы устанавливать contentMode на самой кнопке, вы захотите установить свойства contentHorizontalAlignment и contentVerticalAlignment и (что особенно важно) contentMode для кнопки imageView для любого вида заполнения или подгонки. Вот пример:

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Конечно, вы также можете делать другие вещи, например, выравнивать изображение кнопки по верхнему краю кнопки. Если вам не нужна заливка или подгонка аспекта, вы можете просто установить выравнивание отдельно:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

В Swift вы захотите использовать:

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

Это работает для всех версий iOS, включая последние версии с автоматическим макетом (т. е. с iOS 4 до iOS 11+).

person Chris Nolet    schedule 30.10.2011
comment
Спасибо, Крис - это решило мою проблему, точнее, в сочетании с contentEdgeInsets, чтобы немного отодвинуть мое изображение от верхнего края. - person Rob Reuss; 04.02.2012

После пары часов путаницы, вот как я заставил его работать под iOS 3.2. Как упомянул Дакер, использование setBackgroundImage вместо setImage помогло мне.

CGRect myButtonFrame = CGRectMake(0, 0, 250, 250);
UIImage *myButtonImage = [UIImage imageNamed:@"buttonImage"];

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];

[myButton setBackgroundImage:myButtonImage forState:UIControlStateNormal];
[myButton setFrame: myButtonFrame];
[myButton setContentMode: UIViewContentModeScaleAspectFit];
person Pierre    schedule 02.10.2010

Ответ заключается в том, чтобы использовать UIImageView со всеми нужными настройками Content Mode, а затем наложить на него пользовательскую кнопку. Глупо, что вы не можете сделать все это одним выстрелом, но, похоже, вы не можете.

person Dan Ray    schedule 04.06.2010

Нашел исправление для этого. Установите для свойства adjustsImageWhenHighlighted элемента UIButton значение NO.

  UIButton *b = [[UIButton alloc] initWithFrame:rect];
        [b setImage:image forState:UIControlStateNormal];
        [b.imageView setContentMode:UIViewContentModeScaleAspectFill];
        [b setAdjustsImageWhenHighlighted:NO];

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

person iOSDevSF    schedule 10.06.2012
comment
Это идеальное решение. - person Gaurav; 05.09.2013
comment
Не работает. Это просто предотвращает выделение кнопки. - person Matt; 29.01.2015

Мой ответ похож на ответ Кубы. Мне нужно было, чтобы мой образ был установлен программно.

UIImage *image = [[UIImage alloc] initWithContentsOfFile:...];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill; //this is needed for some reason, won't work without it.
for(UIView *view in button.subviews) {
    view.contentMode = UIViewContentModeScaleAspectFill;
}
person ninjaneer    schedule 06.03.2014

Эти две вещи (которые довольно сложно найти изначально) растянут изображение вашего UIButton, чтобы оно соответствовало размеру кнопки:

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

всегда следует пытаться установить это в раскадровке, а не в коде.

person delta2flat    schedule 12.12.2019
comment
Ты мой герой! - person Carl Smith; 16.05.2021

Единственное решение, которое сработало для меня:

[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
person Tariq    schedule 14.07.2015

Свифт 3

self.firstButton.imageView?.contentMode = .scaleAspectFill
person Vaibhav Saran    schedule 05.09.2017

Вместо setImage попробуйте setBackgroundImage

person dusker    schedule 01.06.2010
comment
Хмп. A, это глупо, он должен учитывать настройку CONTENT MODE для своего СОДЕРЖИМОГО, верно? И B, он ВСЕ ЕЩЕ не соблюдает настройку режима - теперь он заблокирован для растяжения (что в данном случае больше похоже на сжатие) и не масштабирует содержимое в соответствии с его соотношением сторон. - person Dan Ray; 01.06.2010

Я полагаю, что здесь у нас есть простая проблема со сборщиком интерфейса - очевидно, IB игнорирует любые изменения режима содержимого ПОСЛЕ того, как вы установили свойство изображения.

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

person JohnPayne    schedule 19.01.2013
comment
то же самое касается программно установленного content-mode — не устанавливайте изображение ДО установки content-mode - person JohnPayne; 20.01.2013

Также советую обратить внимание на свойство adjustsImageWhenHighlighted UIButton, чтобы избежать странных деформаций изображения при нажатии на кнопку.

person MonsieurDart    schedule 07.10.2010

Пытаясь понять это, мой метод с течением времени стал немного более хакерским, и я закончил создание подкласса UIButton и переопределение setHighlighted:

Для меня это работает, чтобы просто сбить альфу изображения до 0,5, потому что они на черном фоне.

Однако это работает только в том случае, если я закомментирую [super setHighlighted:] (где, похоже, происходит код растягивания изображения), что просто не похоже на правильный способ решить эту проблему вообще... все кажется хотя работает нормально. Посмотрим, как он выдержит, пока я продолжаю над ним работать.

- (void)setHighlighted:(BOOL)highlight {
    if (highlight) {
        [self.imageView setAlpha:.5];
    }  else {
        [self.imageView setAlpha:1];        
    }

//    [super setHighlighted:highlight];
}
person jankins    schedule 28.02.2012
comment
На случай, если кто-то сочтет это актуальным, мой описанный выше метод, казалось, работал нормально, пока я не поместил кнопки в UIScrollView, где иногда застревало выделение кнопки, что, как я подозревал, может в конечном итоге произойти. - person jankins; 03.03.2012

Если кто-то ищет ответ, который работает в iOS 6 и iOS 7 и раскадровке:

Вы можете установить изображение в своей раскадровке:

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

А потом:

for(UIView* testId in self.subviews) {
    if([testId isKindOfClass:[UIImageView class]])
        [testId setContentMode:UIViewContentModeScaleAspectFill];
}
person Jakub    schedule 21.06.2013

Если кажется, что UIButton не прислушивается к настройкам ограничения макета, проверьте, больше ли изображения, чем размер кнопки. Всегда используйте изображения @2x и @3x для разрешения сетчатки.

person Totoro    schedule 20.09.2016