UIButton не перейде на Aspect Fit в iPhone


105

У мене є пара UIButtons, і в IB вони встановлені на Aspect Fit, але чомусь вони завжди розтягуються. Чи є ще щось, що ви повинні встановити? Я спробував всі різні режими перегляду, і жоден з них не працює, всі вони розтягуються.


Відповідь @Werner Altesischer є правильною. Внесіть відповідні зміни.
Харшит Гупта

1
@marty Ви встановлюєте фонове зображення чи зображення? фонове зображення його не підтримує, лише зображення.
Хуан Боеро

Відповіді:


45

У мене була ця проблема раніше. Я вирішив це, поставивши своє зображення в UIImageView, де contentModeфактично працюють налаштування, і над цим поставивши прозорий звичай UIButton.

EDIT: Ця відповідь застаріла. Див відповідь @Werner Altewischer в для правильної відповіді в сучасних версіях IOS.


Так, спробував це, але тепер не вдається отримати кнопку для поновлення зображення
март

Як ви керуєте станами кнопок за допомогою цієї методики? Схоже, реагування на взаємодію користувачів на зразок "виділеного" було б кошмаром.
SooDesuNe

3
Це, можливо, було правильним способом зробити це 2,5 роки тому, коли на це питання було дано відповідь, але тепер ви можете відредагувати внутрішній ImageView UIButton та встановити режим вмісту там. Дивіться відповідь @Werner Altewischer
Стів Хейлі

233

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


67
Це працювало для мене:[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
ayreguitar

2
Це також працює для мене, але якщо я встановив налаштуванняImageWhenHighli žar = ТАК, зображення знову розтягується, коли натискаю кнопку.
cduck

1
Розтягнення в налаштуваннях зображення було усунено в iOS 6.
Бен Флін

3
В iOS 8 це для мене насправді не працює. Оригінальна відповідь (розміщення imageView за прозорою кнопкою) найкраще працює.
користувач1416564

3
у Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Нестор

57

Цей метод спрацював для мене дуже добре:

У Xib виберіть кнопку та встановіть user defined runtime attributes:

  • Ключовий шлях: self.imageView.contentMode
  • Тип: Number
  • Значення: 1

Клацніть тут, щоб побачити більш чітко рішення

Ми використовуємо номер, тому що ви не можете використовувати enum там. Але UIViewContentModeScaleAspectFit дорівнює 1.


2
Це також оновило зображення в конструкторі інтерфейсів під час проектування. Прекрасне рішення.
Джордж Філіппакос

Прекрасне рішення, мало коду і працює як шарм, перерахунок заснований на елементах списку вмістового режиму.
Кросс

Ви також можете додати розширення, щоб зробити його легше: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat

Без 'я' imageView.contentModeпрацював для мене!
byJeevan

22

Якщо ви робите це в Interface Builder, ви можете скористатися інспектором атрибутів Runtime, щоб встановити це безпосередньо без будь-якого коду.

Встановіть свій клавішний шлях на кнопці як "imageView.contentMode" з типом "Число" та значенням "1" (або залежно від режиму).

imageview.contentMode = 1


14

Використовуйте imageView кнопки для contentMode. Не безпосередньо на самій кнопці.

homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];

6

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

Якщо ми хочемо, щоб зображення було нерозкритим для всіх станів управління , одна програма - це отримати зображення за допомогою imageWithCGImage:scale:orientation, як у наступному методі:

- (UIImage *) getScaledImage:(UIImage *)img insideButton:(UIButton *)btn {

    // Check which dimension (width or height) to pay respect to and
    // calculate the scale factor
    CGFloat imgRatio = img.size.width / img.size.height, 
            btnRatio = btn.frame.size.width / btn.frame.size.height,
            scaleFactor = (imgRatio > btnRatio 
                           ? img.size.width / btn.frame.size.width
                           : img.size.height / btn.frame.size.height;

    // Create image using scale factor
    UIImage *scaledImg = [UIImage imageWithCGImage:[img CGImage]
                                             scale:scaleFactor
                                       orientation:UIImageOrientationUp];
    return scaledImg;
}

Для цього ми б написали:

UIImage *scaledImg = [self getScaledImage:myBtnImg insideButton:myBtn];
[myBtn setImage:scaledImg forState:UIControlStateNormal];

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

ПРИМІТКА. Тут ми вирішуємо проблему, яка стосується UIButton, але insideButton:може бути insideView:, або будь-який, хто хотів би вмістити зображення.


6

У мене ця проблема була деякий час назад. У мене виникло питання: я намагався застосувати цей ефект до фонового режиму UIButton, який є обмеженим, а значить, ви не можете налаштувати його настільки просто.

Хитрість полягає в тому, щоб встановити його як просто зображення, а потім застосувати техніку @ ayreguitar і це має виправити!

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];

4

Це працювало для мене

[button.imageView setContentMode:UIViewContentModeScaleAspectFit];

Дякуємо @ayreguitar за його коментар



4

Об’єднавши кілька варіантів відповідей в одне рішення - створіть кнопку з користувацьким типом, встановіть властивість imageView contentMode кнопки та встановіть зображення для кнопки (не фонове зображення, яке все ще буде масштабуватись для заповнення).

//Objective-C:
UIImage *image = [UIImage imageNamed:"myImageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

//Swift:
let image = UIImage(named: "myImageName.png")
let button = UIButton(type: .custom)
button.imageView?.contentMode = .scaleAspectFit
button.setImage(image, for: .normal)

3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;

Хоча цей фрагмент коду може вирішити питання, зокрема пояснення дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду. - З огляду
Феррібіг

2

Ця відповідь ґрунтується на відповіді @ WernerAltewischer .

Щоб уникнути підключення моєї кнопки до IBOutlet для виконання коду на ній, я підкласифікував клас UIButton:

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

- (void) awakeFromNib {
    [self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}

@end



Тепер створіть власну кнопку у своєму xib та встановіть її зображення (а не фонове зображення):

UIButtonWithImageAspectFit: створити та встановити зображення


Потім встановіть його клас:

UIButtonWithImageAspectFit: встановити спеціальний клас

Ви закінчили!
Замість
UIButton без зображення зображення
аспекту зображення вашої кнопки зараз підходить відповідне очікування:
Підходить UIButton з аспектом зображення


2

ios 12. Вам потрібно також додати вміст Вирівнювання

class FitButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)


    }

    override func layoutSubviews() {
        self.imageView?.contentMode = .scaleAspectFill
        self.contentHorizontalAlignment = .fill
        self.contentVerticalAlignment = .fill
        super.layoutSubviews()


    }

}

1

У мене виникли проблеми з розміром зображення не пропорційно, тому спосіб, який я виправляв, використовував крайові вставки.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

1

Режими вмісту UIView застосовуються до відповідного "вмісту" CALayer. Це працює для UIImageViews, оскільки вони встановлюють CALayerвміст відповідним CGImage.

drawRect: в кінцевому рахунку надає вміст шару.

На замовлення UIButton(наскільки я знаю) немає вмісту (кнопки стилю округлої прямої форми можуть бути відображені за допомогою вмісту). Кнопка має підперегляди: фон UIImageView, зображення UIImageViewта заголовок UILabel. Встановлення в contentModeпідпоглядах може робити все, що ви хочете, але возитися з UIButtonієрархією перегляду - це трохи ні-ні.


1

Зміна UIButton.imageView.contentModeдля мене не працює.
Я вирішив проблему, встановивши зображення на властивість "Фон".
Ви можете додати обмеження відношення, якщо вам потрібно


1

Це перекриває багато інших відповідей, але рішенням для мене було це

  • встановити contentModeз UIImageViewза кнопки на .ScaleAspectFit- які або може бути зроблено в «User Defined виконання Атрибути» в Interface Builder (тобто. self.imageView.contentMode, номер, 1) або в UIButtonпідкласі;
  • вимкнути "Автоматизувати перегляди";
  • встановіть "Edge" на "Image" та відповідні значення "Top" та "Bottom" для "Inset" (які, можливо, знадобляться лише у тому випадку, якщо ви, як і я, використовували PDF як зображення).

0

Ви можете використовувати imageWithCGImage, як показано вище (але без відсутніх дужок).

Крім того ... мільйони телефонів, які не є 4.0, взагалі не працюватимуть з цим кодом.



0

Подібно до @Guillaume, я створив підклас UIButton як Swift-File. Потім встановіть мій спеціальний клас у програмі інтерфейсу:

конструктор інтерфейсів.

І ось файл Swift:

import UIKit

class TRAspectButton : UIButton {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.imageView?.contentMode = .ScaleAspectFit
    }
}

-1

У мене була така ж проблема, але я не зміг змусити її працювати (можливо, це помилка з SDK).

Зрештою, як вирішення, я помістив UIImageViewпозаду своєї кнопки і встановив потрібні для цього варіанти, а потім просто розмістив порожню UIButtonповерх неї.


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