Подтвердить что ты не робот

UIButton не пойдет в Aspect Fit на iPhone

У меня есть пара UIButtons, а в IB они настроены на Aspect Fit, но по какой-то причине они всегда растягиваются. Есть что-то еще, что вам нужно установить? Я пробовал все разные режимы просмотра, и никто из них не работает, все они растягиваются.

4b9b3361

Ответ 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

Click here to see more clearly the solution

Мы используем номер, потому что вы не можете использовать перечисление там. Но UIViewContentModeScaleAspectFit равен 1.

Ответ 4

Если вы делаете это в Interface Builder, вы можете использовать инспектор атрибутов Runtime, чтобы установить это прямо без какого-либо кода.

Настройте свой пул клавиш на кнопке как "imageView.contentMode" с типом "Число" и значением "1" (или в зависимости от того, какой режим вы хотите).

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 и установите ее образ (а не фоновое изображение):

UIButtonWithImageAspectFit: create and set image


Затем задайте его класс:

UIButtonWithImageAspectFit: set custom class

Вы закончили!
Вместо того, чтобы UIButton without image aspect fit
ваш образ изображения с изображением кнопки выглядит так, как ожидалось:
UIButton with image aspect fit

Ответ 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.