Как масштабировать imageView UIButton?


81

Я создал экземпляр UIButton с именем «button» с изображением, используя [UIButton setImage:forState:]. Размер button.frame превышает размер изображения.

Теперь я хочу уменьшить изображение этой кнопки. Я пробовал менять button.imageView.frame, button.imageView.boundsи button.imageView.contentMode, но все оказалось безрезультатно.

Может ли кто-нибудь помочь мне масштабировать UIButtonimageView?

Я создал вот UIButtonтак:

UIButton *button = [[UIButton alloc] init];
[button setImage:image forState:UIControlStateNormal];

Я пытался масштабировать изображение вот так:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.bounds = CGRectMake(0, 0, 70, 70);

и это:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.frame = CGRectMake(0, 0, 70, 70);

Ответы:


90

Вот решение, которое я нашел для исходного плаката:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Это позволит вашей кнопке масштабироваться по горизонтали. Также есть вертикальная установка.

Мне потребовалось несколько часов, чтобы понять это (название собственности очень неинтуитивно), поэтому решил, что поделюсь.


хорошее предложение! Моя проблема заключалась в масштабировании растянутого изображения, чтобы изменить размер кнопки leftbaritem в зависимости от ее заголовка.
Валерий Павлов

1
Это работает, но не выводит за границы, думайте об этом как о выравнивании текста в строке, при которой у вас не будет ничего, выходящего за поля. Таким образом, вы не получите эффекта типа UIViewContentModeScaleAspectFill (с обрезанной частью изображения) от этого.
Hlung 02

67

Я столкнулся с аналогичной проблемой, когда у меня было фоновое изображение (одно с рамкой) и изображение (флаг) для настраиваемой кнопки. Я хотел, чтобы флаг был уменьшен и по центру. Я попытался изменить атрибут imageView, но не смог и увидел это изображение -

введите описание изображения здесь

В ходе экспериментов я пробовал:

button.imageEdgeInsets = UIEdgeInsetsMake(kTop,kLeft,kBottom,kRight)

Я добился ожидаемого результата:

введите описание изображения здесь


42

Дополнительный способ конфигурации в файле XIB. Вы можете выбрать этот вариант, если хотите, чтобы текст или изображение были масштабированы до полной заливки в UIButton. То же самое и с кодом.

UIButton *btn = [UIButton new];

btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
btn.contentVerticalAlignment   = UIControlContentVerticalAlignmentFill;

введите описание изображения здесь


Если вы хотите растянуть изображение для UIButton, это идеально, тогда вы можете использовать дополнительную поддержку ресурса изображения и нарезать это изображение. developer.apple.com/library/ios/recipes/…
Линь Нгуен

Даже не знал об этом методе. Rock on
Майкл Маккенна

23

использовать

button.contentMode = UIViewContentModeScaleToFill;

не

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Обновить:

Как прокомментировал @Chris,

Чтобы заставить это работать для setImage: forState :, вам нужно сделать следующее для горизонтального масштабирования: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;


3
Это прекрасно работает в сочетании с [button setBackgroundImage: forState:]. Благодарю.
Джейсон ДеФонтес,

Запомните, что именно сказал Джейсон, и все будет хорошо. Это не работает для setImage: forState:
dpjanes 01

7
Чтобы заставить это работать для setImage: forState :, вам необходимо сделать следующее для горизонтального масштабирования: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
Крис

15
    UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(0,0,70,70)];
    button.buttonType = UIButtonTypeCustom;
    UIImage *buttonImage = [UIImage imageNamed:@"image.png"];

    UIImage *stretchableButtonImage = [buttonImage stretchableImageWithLeftCapWidth:12 topCapHeight:0]; 
    [button setBackgroundImage:stretchableButtonImage forState:UIControlStateNormal]; 

@EEE Спасибо. Но есть 2 проблемы: 1. Мой вопрос заключается в использовании переменной _imageView UIButton, а не переменной _backgroundView. Должен ли я делать это с помощью backgroundView? 2. функция [UIImage stretchImageWithLeftCapWidth: topCapHeight:] может только увеличивать изображение, но не может уменьшать изображение. Тем не менее, спасибо, и ваш ответ решает мой другой вопрос: я хочу нарисовать заголовок на кнопке с изображением позади. Я думаю, что _backgroundImage может мне помочь. Есть ли на этот вопрос другой лучший ответ?
vcLwei

Я вижу, что вы пытаетесь сделать, и это правильный путь. если ваше изображение больше, измените его размер с помощью инструмента, и все, что вы хотите сделать, будет сделано. Не тратьте время на with_imageview. Кстати, если вам нравится этот ответ, вы можете проголосовать за него и принять
EEE

Вы можете изменить размер изображения в программе предварительного просмотра в MacOS. Просто откройте инструменты изображения и выбора -> Adjustize
EEE

@EEE Да, я могу изменить размер изображения с помощью инструмента. Но в моем приложении иногда мне тоже нужно изображение побольше, я не хочу, чтобы два похожих изображения только различались по размеру, что слишком тратит место. И еще один способ решить мой вопрос - это то, что я могу использовать CGBitmapContext для получения меньшего изображения, но я предполагаю, что этот способ неудобен по сравнению с использованием _imageview. Причина, по которой я не проголосовал за это, - моя репутация ниже 15, на самом деле я действительно хочу это сделать. Благодаря!
vcLwei

10

Я нашел это решение.

1) Подклассифицируйте следующие методы UIButton

+ (id)buttonWithType:(UIButtonType)buttonType {
    MyButton *toReturn = [super buttonWithType:buttonType];
    toReturn.imageView.contentMode = UIViewContentModeScaleAspectFit;
    return toReturn;
}

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    return contentRect;
}

И это хорошо работает.


- (CGRect) backgroundRectForBounds: (CGRect) границы для фонового изображения.
Ricky

9

Странно, единственная комбинация, которая у меня сработала (iOS 5.1), это ...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

и

[button setImage:newImage forState:UIControlStateNormal];


Изначально я использовал: button.contentMode = UIViewContentModeScaleAspectFit; теперь мне также нужно написать button.imageView.contentMode = UIViewContentModeScaleAspectFit; сохранить соотношение сторон на сетчатке iPad 3
Энрико Детома

8

Просто сделайте (из дизайна ИЛИ из кода):

От дизайна

  1. Откройте свой xib OR Storyboard.
  2. Кнопка выбора
  3. Внутренний инспектор атрибутов (правая сторона)> В разделе «Управление» > выберите последний 4-й вариант для горизонтального и вертикального.

[Для точки №3: измените выравнивание по горизонтали и вертикали на UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

Из кода

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;


5

как это может решить вашу проблему:

+ (UIImage*)resizedImage:(UIImage*)image
{
 CGRect frame = CGRectMake(0, 0, 60, 60);
 UIGraphicsBeginImageContext(frame.size);
 [image drawInRect:frame];
 UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();

 return resizedImage;
}

5

Из небольшого теста, который я только что сделал после прочтения здесь, зависит от того, используете ли вы setImage или setBackgroundImage, оба дали тот же результат и растянули изображение

//for setBackgroundImage
 self.imageButton.contentMode = UIViewContentModeScaleAspectFill;
        [self.imageButton setBackgroundImage:[UIImage imageNamed:@"imgFileName"] forState:UIControlStateNormal];

//for setImage
 self.imageButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
        self.imageButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
    [self.imageButton setImage:[UIImage imageNamed:@"imgFileName"] forState:UIControlStateNormal];

спасибо за тонну ... идеальное решение для подгонки небольшого изображения размером меньше, чем размер пуговицы ...
Фахим Паркар

4
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;

2

Это также будет работать, поскольку backgroundImage автоматически масштабируется

[button setBackgroundImage:image forState:UIControlStateNormal];


2

Раскадровка

Вы должны определить конкретное свойство в Runtime Attributes of Identity Inspector - imageView.contentModel, где вы устанавливаете значение относительно rawValueпозиции перечисления UIViewContentMode. 1 означает scaleAspectFit .

Установите button.imageView.contentMode в раскадровке

И выравнивание кнопки в инспекторе атрибутов :

Полное выравнивание кнопки


1

Я не могу использовать решение с помощью _imageView, но могу использовать CGContextRefдля его решения. Он использует UIGraphicsGetCurrentContextдля получения currentContextRef и рисования изображения в currentContextRef, а затем масштабирует или вращает изображение и создает новое изображение. Но это не идеально.

код:

-(UIImage*) scaleAndRotateImage:(UIImage*)photoimage width:(CGFloat)bounds_width height:(CGFloat)bounds_height;
{
    CGImageRef imgRef = photoimage.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);

    bounds.size.width = bounds_width;
    bounds.size.height = bounds_height;

    CGFloat scaleRatio = bounds.size.width / width;
    CGFloat scaleRatioheight = bounds.size.height / height;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = photoimage.imageOrientation;
    switch(orient)
    {
        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid?image?orientation"];
            break;
    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
    {
        CGContextScaleCTM(context, -scaleRatio, scaleRatioheight);
        CGContextTranslateCTM(context, -height, 0);
    }
    else
    {
        CGContextScaleCTM(context, scaleRatio, -scaleRatioheight);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageCopy;
}

1

Надеюсь, это поможет кому-то другому:

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill



-1

У каждого UIButton есть собственный скрытый UIImageView. Итак, мы должны установить режим содержимого, как показано ниже ...

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

-1

Скриншот в XCode 8

В левом нижнем углу скриншота вы можете увидеть свойства растяжения. Попробуйте использовать те.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.