У меня есть пара 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.contentMode
Number
1
Мы используем число, потому что вы не можете использовать там 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. Это работает для UIImageView
s, потому что они устанавливают соответствующий 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
для нее нужные параметры, а затем просто поместил поверх нее пробел .