У мене є пара UIButtons, і в IB вони встановлені на Aspect Fit, але чомусь вони завжди розтягуються. Чи є ще щось, що ви повинні встановити? Я спробував всі різні режими перегляду, і жоден з них не працює, всі вони розтягуються.
У мене є пара UIButtons, і в IB вони встановлені на Aspect Fit, але чомусь вони завжди розтягуються. Чи є ще щось, що ви повинні встановити? Я спробував всі різні режими перегляду, і жоден з них не працює, всі вони розтягуються.
Відповіді:
У мене була ця проблема раніше. Я вирішив це, поставивши своє зображення в UIImageView, де contentModeфактично працюють налаштування, і над цим поставивши прозорий звичай UIButton.
EDIT: Ця відповідь застаріла. Див відповідь @Werner Altewischer в для правильної відповіді в сучасних версіях IOS.
Рішення полягає в тому, щоб встановити contentModeна imageViewвласність з UIButton. UIButtonПовинен бути створений з допомогою призначеного для користувача типу для цієї роботи я вважаю , ( в іншому випадку nilповертається для цієї властивості).
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Цей метод спрацював для мене дуже добре:
У Xib виберіть кнопку та встановіть user defined runtime attributes:
self.imageView.contentModeNumber1
Ми використовуємо номер, тому що ви не можете використовувати enum там. Але UIViewContentModeScaleAspectFit дорівнює 1.
extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
imageView.contentModeпрацював для мене!
Використовуйте imageView кнопки для contentMode. Не безпосередньо на самій кнопці.
homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];
Якщо ви помістите зображення 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:, або будь-який, хто хотів би вмістити зображення.
У мене ця проблема була деякий час назад. У мене виникло питання: я намагався застосувати цей ефект до фонового режиму UIButton, який є обмеженим, а значить, ви не можете налаштувати його настільки просто.
Хитрість полягає в тому, щоб встановити його як просто зображення, а потім застосувати техніку @ ayreguitar і це має виправити!
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];
Це працювало для мене
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
Дякуємо @ayreguitar за його коментар
Ось швидка альтернативна відповідь:
myButton.imageView?.contentMode = .ScaleAspectFit
Об’єднавши кілька варіантів відповідей в одне рішення - створіть кнопку з користувацьким типом, встановіть властивість 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)
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
Ця відповідь ґрунтується на відповіді @ WernerAltewischer .
Щоб уникнути підключення моєї кнопки до IBOutlet для виконання коду на ній, я підкласифікував клас UIButton:
// .h
@interface UIButtonWithImageAspectFit : UIButton
@end
// .m
@implementation UIButtonWithImageAspectFit
- (void) awakeFromNib {
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}
@end
Тепер створіть власну кнопку у своєму xib та встановіть її зображення (а не фонове зображення):

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

Ви закінчили!
Замість

аспекту зображення вашої кнопки зараз підходить відповідне очікування:

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()
}
}
Режими вмісту UIView застосовуються до відповідного "вмісту" CALayer. Це працює для UIImageViews, оскільки вони встановлюють CALayerвміст відповідним CGImage.
drawRect: в кінцевому рахунку надає вміст шару.
На замовлення UIButton(наскільки я знаю) немає вмісту (кнопки стилю округлої прямої форми можуть бути відображені за допомогою вмісту). Кнопка має підперегляди: фон UIImageView, зображення UIImageViewта заголовок UILabel. Встановлення в contentModeпідпоглядах може робити все, що ви хочете, але возитися з UIButtonієрархією перегляду - це трохи ні-ні.
Зміна UIButton.imageView.contentModeдля мене не працює.
Я вирішив проблему, встановивши зображення на властивість "Фон".
Ви можете додати обмеження відношення, якщо вам потрібно
Це перекриває багато інших відповідей, але рішенням для мене було це
contentModeз UIImageViewза кнопки на .ScaleAspectFit- які або може бути зроблено в «User Defined виконання Атрибути» в Interface Builder (тобто. self.imageView.contentMode, номер, 1) або в UIButtonпідкласі;Подібно до @Guillaume, я створив підклас UIButton як Swift-File. Потім встановіть мій спеціальний клас у програмі інтерфейсу:
І ось файл Swift:
import UIKit
class TRAspectButton : UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .ScaleAspectFit
}
}
У мене була така ж проблема, але я не зміг змусити її працювати (можливо, це помилка з SDK).
Зрештою, як вирішення, я помістив UIImageViewпозаду своєї кнопки і встановив потрібні для цього варіанти, а потім просто розмістив порожню UIButtonповерх неї.