Как масштабировать 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);
vcLwei
источник

Ответы:

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
источник
@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];

Hlung
источник
Изначально я использовал: 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;
Сандип Патель - SM
источник
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];
user1105951
источник
спасибо за тонну ... идеальное решение для подгонки небольшого изображения размером меньше, чем размер пуговицы ...
Фахим Паркар
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;
}
vcLwei
источник
1

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

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill
Дашога
источник
0

из @JosephH

contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.fill contentVerticalAlignment = UIControl.ContentVerticalAlignment.fill

Майкл Колонна
источник
-1

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

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
Emraz
источник
-1

Скриншот в XCode 8

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

Суровый Г.
источник