У меня есть пара UIButtons, а в IB они настроены на Aspect Fit, но по какой-то причине они всегда растягиваются. Есть что-то еще, что вам нужно установить? Я пробовал все разные режимы просмотра, и никто из них не работает, все они растягиваются.
UIButton не пойдет в Aspect Fit на iPhone
Ответ 1
У меня была эта проблема раньше. Я решил это, поставив свое изображение в UIImageView
, где действительно выполняются настройки contentMode
, и помещая прозрачный пользовательский UIButton
поверх этого.
EDIT: этот ответ устарел. См. @Werner Altewischer answer для правильного ответа в современных версиях iOS.
Ответ 2
Решение состоит в том, чтобы установить contentMode
в свойстве imageView
UIButton
. UIButton
должен быть создан с настраиваемым типом для этого, я верю (иначе nil
возвращается для этого свойства).
Ответ 3
Этот метод работал у меня очень хорошо.:
В Xib выберите кнопку и установите user defined runtime attributes
:
- Путь к ключу:
self.imageView.contentMode
- Тип:
Number
- Значение:
1
Мы используем номер, потому что вы не можете использовать перечисление там. Но UIViewContentModeScaleAspectFit равен 1.
Ответ 4
Если вы делаете это в Interface Builder, вы можете использовать инспектор атрибутов Runtime, чтобы установить это прямо без какого-либо кода.
Настройте свой пул клавиш на кнопке как "imageView.contentMode" с типом "Число" и значением "1" (или в зависимости от того, какой режим вы хотите).
Ответ 5
Используйте кнопку 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:
или тому, что хотелось бы поместить в изображение.
Ответ 7
У меня была эта проблема некоторое время назад. Проблема, с которой я столкнулся, заключалась в том, что я пытался применить этот эффект к фону UIButton, который ограничен, и поэтому означает, что вы не можете легко его отрегулировать.
Трюк заключается в том, чтобы установить его как только изображение, затем применить технику @ayreguitar, и это должно исправить это!
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];
Ответ 8
Это сработало для меня
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
Спасибо @ayreguitar за его комментарий
Ответ 9
Вот альтернативный ответ в быстрой:
myButton.imageView?.contentMode = .ScaleAspectFit
Ответ 10
Объединяя несколько разных ответов в одном решении - создайте кнопку с настраиваемым типом, установите свойство 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)
Ответ 11
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
Ответ 12
Этот ответ основан на ответе @WernerAltewischer.
Чтобы избежать подключения моей кнопки к IBOutlet для выполнения кода на ней, я подклассифицировал класс UIButton:
// .h
@interface UIButtonWithImageAspectFit : UIButton
@end
// .m
@implementation UIButtonWithImageAspectFit
- (void) awakeFromNib {
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}
@end
Теперь создайте пользовательскую кнопку в xib и установите ее образ (а не фоновое изображение):
Затем задайте его класс:
Вы закончили!
Вместо того, чтобы
ваш образ изображения с изображением кнопки выглядит так, как ожидалось:
Ответ 13
Режимы содержимого UIView применяются к соответствующему "содержимому" CALayer. Это работает для UIImageView
, потому что они устанавливают содержимое CALayer
на соответствующий CGImage
.
drawRect:
в конечном итоге отображает содержимое слоя.
Пользовательский UIButton
(насколько мне известно) не имеет содержимого (кнопки с закругленными строками могут отображаться с использованием содержимого). У кнопки есть подвид: фон UIImageView
, изображение UIImageView
и заголовок UILabel
. Установка contentMode
в подзаголовках может делать то, что вы хотите, но возиться с иерархией представлений UIButton
- это бит no-no.
Ответ 14
У меня были проблемы с изображением, не изменяющим размер пропорционально, так что я исправил его с помощью кросс-вложений.
fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
Ответ 15
Это перекрывает многие другие ответы, но решение для меня было
- установите
contentMode
дляUIImageView
для кнопки.ScaleAspectFit
- которая может быть выполнена в "Определенных пользователем атрибутах времени выполнения" в Interface Builder (например,self.imageView.contentMode
, Number, 1) или вUIButton
подкласс; - отключить "Autoresize Subviews";
- установите "Edge" в "Image" и соответствующие значения "Top" и "Bottom" для "Inset" (которые могут потребоваться только в том случае, если вы, как и я, использовали PDF как изображение).
Ответ 16
Вы можете использовать imageWithCGImage, как показано выше (но без отсутствующих скобок).
Также... миллионы телефонов, не относящихся к 4.0, вообще не будут работать с этим кодом.
Ответ 17
[button sizeToFit]
работал у меня.
Ответ 18
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()
}
}
Ответ 19
Изменение UIButton.imageView.contentMode
не работает для меня.
Я решил проблему, установив изображение в свойство "Фон".
Вы можете добавить ограничение отношения, если вам нужно
Ответ 20
Подобно @Guillaume, я создал подкласс UIButton как Swift-File. Затем установите свой собственный класс в построителе интерфейса:
И вот файл Swift:
import UIKit
class TRAspectButton : UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .ScaleAspectFit
}
}
Ответ 21
У меня была такая же проблема, но я не мог заставить ее работать (возможно, это ошибка с SDK).
В конце концов, в качестве обходного пути я разместил UIImageView
за моей кнопкой и задал нужные мне параметры, а затем просто поместил на него пустой UIButton
.