У меня есть пара UIButton, и в IB они настроены на Aspect Fit, но по какой-то причине они всегда растягиваются. Вам нужно что-то еще установить? Я перепробовал все разные режимы просмотра, и ни один из них не работает, все растягиваются.
У меня есть пара UIButton, и в IB они настроены на Aspect Fit, но по какой-то причине они всегда растягиваются. Вам нужно что-то еще установить? Я перепробовал все разные режимы просмотра, и ни один из них не работает, все растягиваются.
Ответы:
У меня была такая проблема раньше. Я решил это, поместив свое изображение в UIImageView, где contentModeнастройки действительно работают, и поместив UIButtonповерх него прозрачный пользовательский .
РЕДАКТИРОВАТЬ: этот ответ устарел. См. Ответ @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у меня работало!
Если вы делаете это в Interface Builder, вы можете использовать инспектор атрибутов среды выполнения, чтобы установить это напрямую без какого-либо кода.
Задайте для ключевого пути на кнопке значение «imageView.contentMode» с типом «Число» и значением «1» (или любым другим режимом, который вам нужен).
Используйте кнопку 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. Также необходимо добавить контент Alignment
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-файл. Затем установите мой собственный класс в Интерфейсном Разработчике:
И вот файл Swift:
import UIKit
class TRAspectButton : UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .ScaleAspectFit
}
}
У меня была такая же проблема, но я не мог заставить ее работать (возможно, это ошибка SDK).
В конце концов, как обходной путь, я поместил UIImageViewза своей кнопкой и установил UIButtonдля нее нужные параметры, а затем просто поместил поверх нее пробел .