UIButton не слухає налаштування режиму вмісту?


91

firstButton - це кнопка UIB типу Custom. Я програмно розміщую три з них у кожній комірці таблиці, таким чином:

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

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


1
Див. Рішення Кріса Нолета нижче: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Matt

Див. Stackoverflow.com/a/28205566/481207, який показує, що для UIViewContentModeScaleAspectFit потрібно встановити як contentVerticalAlignment, так і contentHorizontalAlignment.
Метт,

Відповіді:


187

У мене була та сама проблема. Я бачу, що це питання трохи застаріле, але я хочу дати чітку і правильну відповідь, щоб заощадити іншим людям (таким як я) деякий час, коли воно з’явиться в результатах пошуку.

Мені знадобилося трохи пошуків та експериментів, але я знайшов рішення. Просто встановіть ContentMode "прихованого" ImageView, який знаходиться всередині кнопки UIB.

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

Можливо, на це натякав Ден Рей у своїй прийнятій відповіді, але я підозрюю, що ні.


1
Ні, не було. Рішенням, на якому я зупинився, було використання UIImageView для утримання зображення, а потім прозору прозору UIB-кнопку типу "custom" зверху.
Dan Ray

Дейве, принаймні на iOS 3.2, твоє рішення, здається, не працює для мене. Шкода, бо я сподівався отримати підсвічування зображення натисканням "безкоштовно". Я навіть переконався, що button.imageView не дорівнює нулю там, де я встановлював contentMode, і встановив зображення після встановлення contentMode, як і ви.
Jacques

2
Тільки для уточнення, "не працює" означає "зображення відображається з повною роздільною здатністю, а не зменшене, як я сподівався".
Jacques

Жак, вищесказане працює для мене в iOS 4.x. На жаль, я можу відтворити проблему "не змінює розмір", коли будую з цільовою v3.2. Я спробував змінити розмір кадру подання UIButton, але, здається, це теж не допомогло. тьфу.
Дейв

4
Див. Рішення Кріса Нолета нижче: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Matt

74

Якщо ви маєте справу із зображенням UIButton (на відміну від його backgroundImage), встановлення contentMode на самому UIButton або на його imageView не впливає (незважаючи на те, що говорять інші відповіді).

Або зробіть це замість цього:

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

Або розмір зображення відповідно.

АБО просто використовуйте UIImageView (який належним чином поважає contentMode) із прикріпленим до нього UITapGestureRecognizer або прозорою кнопкою UIB поверх нього.


4
Це працює для мого випадку в iOS 7, тоді як усі інші тут ні.
Байт

5
Встановлення contentHorizontalAlignment і contentVerticalAlignment - правильне рішення. Пояснення див. У статті stackoverflow.com/a/28205566/481207 .
Метт,

1
Це відповідь, яку я шукав.
ninjaneer

4
Ця відповідь неправильна. Ви дійсно повинні встановити contentModeна , imageViewякщо ви хочете зробити будь-який вид заливки сторін або нападу, як і інші відповіді з'ясовані. Довідка: stackoverflow.com/a/7944316/746890 .
Chris Nolet 02

51

Замість того , встановивши 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+).


2
Дякую, Кріс - це вирішило мою проблему, точніше, це було зроблено в поєднанні з contentEdgeInsets, щоб трохи відступити моє зображення від верхнього краю.
Роб Реус

7

Через пару годин плутанини, ось як я змусив його працювати під 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];

6

Відповідь полягає у використанні UIImageView з усіма чудовими налаштуваннями режиму вмісту, які ви хочете, а потім накладіть на нього спеціальну кнопку. Тупо, що ви не можете зробити все за один постріл, але, схоже, ви не можете.


4

Знайшов виправлення для цього. Встановіть adjustsImageWhenHighlightedвластивість UIButtonв NO.

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

Сподіваюся, це допомагає. Не соромтеся коментувати нижче, я буду стежити за будь-якими питаннями, які у вас виникли.


Це ідеальне рішення.
Gaurav

Не працює. Це просто перешкоджає виділенню кнопки.
Метт

4

Моя відповідь подібна до відповіді Куби. Мені потрібно було, щоб моє зображення було встановлено програмно.

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;
}

3

Єдине рішення, яке працювало у мене:

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


1

Замість setImage спробуйте setBackgroundImage


3
Hmp. А, це німо, воно повинно поважати налаштування РЕЖИМ ЗМІСТУ для ЗМІСТУ, так? І B, Здається, ЩЕ ВСЕ не поважає налаштування режиму - тепер він заблокований для "розтягування" (що в даному випадку більше нагадує "стиснути") і не масштабує вміст щодо його аспекту співвідношення.
Dan Ray

1

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

рішення просте: встановіть режим вмісту, видаліть раніше встановлені імена зображень (переконайтеся, що ви видаляєте його у всіх штатах, за замовчуванням, виділено тощо), а потім повторно введіть потрібні імена зображень у всіх бажаних станах - et voilà .


1
те саме стосується програмно встановленого режиму вмісту - не встановлювати зображення ДО встановлення режиму вмісту
ДжонПейн

0

Я також раджу поглянути на adjustsImageWhenHighlighted UIButtonвластивість, щоб уникнути дивних деформацій зображення при натисканні кнопки.


0

Намагаючись зрозуміти це, мій метод став трохи щасливішим із часом, і я завершив підкласифікацію UIButton і перевизначення setHighlighted:

Для мене працює просто збити зображення альфа до .5, тому що вони на чорному тлі.

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

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

//    [super setHighlighted:highlight];
}

1
Із випадковості, що хтось вважає це доречним, мій вищезгаданий метод, здавалося, працював нормально, поки я не поклав кнопки на UIScrollView, де іноді виділення кнопки «застрягло», саме це, як я підозрював, могло врешті-решт статися.
jankins 03.03.12

0

Якщо хтось шукає відповіді, які працюють в iOS 6 та iOS 7 та розкадровці:

Ви можете встановити зображення на своїй розкадровці:

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

І потім:

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

0

Якщо кнопка UIB, здається, не слухає налаштування обмеження макета, перевірте, чи розміри зображень не перевищують розмір кнопки. Завжди використовуйте зображення @ 2x та @ 3x для роздільної здатності сітківки.


0

Ці дві речі (які спочатку досить важко знайти) розтягнуть ваше зображення UIButton відповідно до розміру кнопки:

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

завжди потрібно намагатися встановити таке в Storyboard, а не в коді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.