Як масштабувати UIButton's imageView?


81

Я створив екземпляр UIButton з назвою "button" із зображенням за допомогою [UIButton setImage:forState:]. Button.frame більше розміру зображення.

Тепер я хочу зменшити зображення цієї кнопки менше. Я спробував змінитись button.imageView.frame, button.imageView.boundsі button.imageView.contentMode, але все здається неефективним.

UIButtonХтось може допомогти мені масштабувати imageView?

Я створив 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;

Це дозволить вашій кнопці масштабуватися горизонтально. Існує також вертикальна установка.

Мені знадобилося кілька годин, щоб це зрозуміти (назва власності дуже неінтуїтивна), тож я зрозумів, що поділюсь.


хорошого цукру! моя проблема полягала в масштабуванні розтягнутого зображення, щоб змінити розмір лівої кнопки, що залежить від її заголовка.
Валерій Павлов

1
Це працює, але не буде малювати за межами, вважайте це як вирівнювання тексту в рядку, щоб у вас не було нічого, щоб пройти поля. Отже, ви не отримаєте такого ефекту, як UIViewContentModeScaleAspectFill (з деякою частиною обрізаного зображення) від цього.
Hlung,

67

Я зіткнувся з подібною проблемою, коли у мене є фонове зображення (одне з межею) та зображення (прапор) для власної кнопки. Я хотів, щоб прапор був зменшений і в центрі. Я спробував змінити атрибут imageView, але не вдалося і бачив це зображення -

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

Під час своїх експериментів я спробував:

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

Я досягнув очікуваного результату як:

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


42

Доданий спосіб для налаштування у файлі XIB. Ви можете вибрати цей параметр, якщо ви хочете, щоб текст або зображення мали масштаб Повне заповнення в UIB кнопці. З кодом буде те саме.

UIButton *btn = [UIButton new];

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

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


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

Навіть не знав про цей метод. Rock on
Michael McKenna

23

використання

button.contentMode = UIViewContentModeScaleToFill;

ні

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Оновлення:

Як прокоментував @Chris,

Щоб це працювало для setImage: forState :, потрібно зробити наступне для горизонтального масштабування: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;


3
Це чудово працює в поєднанні з [button setBackgroundImage: forState:]. Дякую.
Джейсон Дефонтес,

Зверніть увагу, що саме сказав Джейсон, і ви будете добре. Це не працює для setImage: forState:
dpjanes

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 stretchchableImageWithLeftCapWidth: topCapHeight:] може лише збільшити зображення, але не може зменшити його. Все одно дякую, і ваша відповідь вирішує моє інше питання: я хочу намалювати заголовок на кнопці із зображенням позаду. Я думаю, що _backgroundImage може мені допомогти. Чи має це запитання іншу кращу відповідь?
vcLwei

Я бачу, що ти намагаєшся зробити, і це шлях. якщо ваше зображення більше, змініть розмір його за допомогою інструменту, і все, що ви хочете зробити, буде зроблено. Не витрачайте час з_imageview. До речі, якщо вам подобається цей відповідь, ви можете проголосувати за нього та прийняти
EEE

Ви можете змінити розмір зображення в програмі попереднього перегляду в MacOS. Просто відкрийте інструменти зображення та селету -> Налаштувати
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) для фонового зображення.
Рікі,

9

Дивно, але єдиною комбінацією, яка працювала у мене (iOS 5.1), є ...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

і

[button setImage:newImage forState:UIControlStateNormal];


Спочатку я використовував: button.contentMode = UIViewContentModeScaleAspectFit; тепер мені також потрібно написати button.imageView.contentMode = UIViewContentModeScaleAspectFit; зберегти пропорції на сітківці iPad 3
Enrico Detoma

8

Просто виконайте (з дизайну АБО з коду):

Від дизайну

  1. Відкрийте свій xib АБО Storyboard.
  2. Кнопка вибору
  3. Внутрішній інспектор атрибутів (справа)> У розділі "Керування" > виберіть останню четверту опцію як для горизонтальної, так і для вертикальної.

[Для точки №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;

3

Розкадровка

Ви повинні визначити конкретну властивість у Runtime Attributes of Identity Inspector - imageView.contentModel, де ви встановлюєте значення щодо rawValueпозиції переліку UIViewContentMode. 1 означає масштабAspectFit .

Встановити button.imageView.contentMode у розкадруванні

І вирівнювання кнопки в інспекторі атрибутів :

Повне вирівнювання кнопки


2

Це також спрацює, оскільки backgroundImage автоматично масштабується

[button setBackgroundImage:image forState:UIControlStateNormal];


1

Я не можу отримати рішення за допомогою _imageView, але я можу використати a 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

Сподіваюся, це може допомогти комусь іншому:

Свіфт 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];

-1

Знімок екрана в XCode 8

У нижньому лівому куті знімка екрана ви можете побачити властивості розтягування. Спробуйте використовувати їх.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.