Jak skalować imageView UIButton?

81

Utworzyłem instancję UIButton o nazwie „przycisk” z obrazem przy użyciu [UIButton setImage:forState:]. Rozmiar button.frame jest większy niż rozmiar obrazu.

Teraz chcę zmniejszyć rozmiar obrazu tego przycisku. Próbowałem zmienia button.imageView.frame, button.imageView.boundsi button.imageView.contentMode, ale wszystkie wydają się nieskuteczne.

Czy ktoś może mi pomóc w skalowaniu UIButtonimageView?

Stworzyłem UIButtontak:

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

Próbowałem skalować obraz w ten sposób:

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

i to:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.frame = CGRectMake(0, 0, 70, 70);
vcLwei
źródło

Odpowiedzi:

90

W przypadku oryginalnego plakatu oto rozwiązanie, które znalazłem:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Umożliwi to skalowanie przycisku w poziomie. Istnieje również ustawienie pionowe.

Wymyślenie tego zajęło mi kilka godzin (nazwanie nieruchomości jest bardzo nieintuicyjne), więc pomyślałem, że podzielę się.

Chris
źródło
dobra sugestia! mój problem polegał na skalowaniu rozciągniętego obrazu w celu zmiany rozmiaru przycisku leftbaritem w zależności od jego tytułu.
Valerii Pavlov
1
To działa, ale nie będzie rysować poza granicami, pomyśl o tym jak o wyrównaniu tekstu w linii, w której nic nie będzie przekraczać marginesów. Więc nie uzyskasz efektu takiego jak UIViewContentModeScaleAspectFill (z przyciętą częścią obrazu) z tego.
Hlung
67

Miałem podobny problem, gdzie mam obraz tła (jeden z obramowaniem) i obraz (flaga) dla niestandardowego przycisku. Chciałem, aby flaga była pomniejszona i na środku. Próbowałem zmienić atrybut imageView, ale nie udało mi się i widziałem ten obraz -

wprowadź opis obrazu tutaj

Podczas moich eksperymentów próbowałem:

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

Osiągnąłem oczekiwany rezultat jako:

wprowadź opis obrazu tutaj

Hitesh Savaliya
źródło
42

Dodatkowy sposób konfiguracji w pliku XIB. Możesz wybrać tę opcję, jeśli chcesz, aby tekst lub obraz był wypełniony pełną skalą w UIButton. Tak samo będzie z kodem.

UIButton *btn = [UIButton new];

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

wprowadź opis obrazu tutaj

Linh Nguyen
źródło
Jeśli chcesz rozciągnąć obraz dla UIButton jest idealnie, możesz użyć większej obsługi zasobu obrazu i cięcia tego obrazu. developer.apple.com/library/ios/recipes/…
Linh Nguyen,
Nie był nawet świadomy tej metody. Rock on
Michael McKenna
23

posługiwać się

button.contentMode = UIViewContentModeScaleToFill;

nie

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Aktualizacja:

Jak skomentował @Chris,

Aby to zadziałało dla setImage: forState:, musisz wykonać następujące czynności, aby skalować w poziomie: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

pavelpanov
źródło
3
Działa to świetnie w połączeniu z [button setBackgroundImage: forState:]. Dzięki.
Jason DeFontes
Zwróć uwagę dokładnie, co powiedział Jason, a będziesz dobry. To nie działa dla setImage: forState:
dpjanes
7
Aby to zadziałało dla setImage: forState:, musisz wykonać następujące czynności, aby skalować w poziomie: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
Chris,
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
źródło
@EEE Dziękuję. Ale są dwa problemy: 1. Moje pytanie dotyczy użycia zmiennej _imageView UIButton, a nie zmiennej _backgroundView. Czy muszę to zrobić za pomocą backgroundView? 2. Funkcja [UIImage stretchableImageWithLeftCapWidth: topCapHeight:] może tylko powiększać obraz, ale nie może zmniejszać obrazu. Mimo wszystko dziękuję, a twoja odpowiedź rozwiązuje moje kolejne pytanie: chcę narysować tytuł na przycisku z obrazkiem za nim. Myślę, że _backgroundImage może mi pomóc. Czy to pytanie ma inną lepszą odpowiedź?
vcLwei
Widzę, co próbujesz zrobić i to jest sposób. jeśli twój obraz jest większy, zmień jego rozmiar za pomocą narzędzia, a wszystko, co chcesz zrobić, zostanie zrobione. Nie trać czasu z_imageview. Nawiasem mówiąc, jeśli podoba Ci się ta odpowiedź, możesz zagłosować i zaakceptować
EEE,
Możesz zmienić rozmiar obrazu w programie podglądu w systemie MacOS. Po prostu otwórz obraz i wybierz narzędzia -> Dostosuj rozmiar
EEE
@EEE Tak, mogę zmienić rozmiar obrazu za pomocą narzędzia. Ale w mojej aplikacji czasami potrzebuję też większego obrazu, nie chcę, aby dwa podobne obrazy różniły się tylko rozmiarem, co zbytnio marnuje miejsce. Innym sposobem rozwiązania mojego pytania jest użycie CGBitmapContext, aby uzyskać mniejszy obraz, ale wydaje mi się, że jest to niewygodne w porównaniu z używaniem _imageview. Powodem, dla którego nie głosowałem za tym, jest moja reputacja poniżej 15, właściwie naprawdę chcę to zrobić. Dzięki!
vcLwei
10

Znalazłem to rozwiązanie.

1) Podklasuj następujące metody UIButton

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

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

I działa dobrze.

marcio
źródło
- (CGRect) backgroundRectForBounds: (CGRect) granice dla obrazu tła.
Ricky
9

Dziwne, jedyne combo, które działało dla mnie (iOS 5.1) to ...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

i

[button setImage:newImage forState:UIControlStateNormal];

Hlung
źródło
Pierwotnie użyłem: button.contentMode = UIViewContentModeScaleAspectFit; teraz muszę też napisać button.imageView.contentMode = UIViewContentModeScaleAspectFit; aby zachować proporcje na siatkówce iPada 3
Enrico Detoma,
8

Po prostu zrób (z projektu lub z kodu):

Od projektu

  1. Otwórz swój xib LUB Storyboard.
  2. Wybierz przycisk
  3. Wewnątrz inspektora atrybutów (prawa strona)> W sekcji „Sterowanie” > wybierz ostatnią czwartą opcję zarówno dla pozycji poziomej, jak i pionowej.

[Dla punktu 3: Zmień wyrównanie w poziomie i w pionie na UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

Z Code

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
Sandip Patel - SM
źródło
5

w ten sposób może rozwiązać twój problem:

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

 return resizedImage;
}
huangkui
źródło
5

Z małego testu, który właśnie zrobiłem po przeczytaniu tutaj, zależy, czy używasz setImage czy setBackgroundImage, oba dały ten sam wynik i rozciągnęły obraz

//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
źródło
wielkie
4
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
iomar
źródło
2

To również zadziała, ponieważ backgroundImage automatycznie się skaluje

[button setBackgroundImage:image forState:UIControlStateNormal];

Harris
źródło
2

Storyboard

Musisz zdefiniować określoną właściwość w Runtime Attributes of Identity inspector - imageView.contentModel, gdzie ustawiasz wartość względem rawValuepozycji wyliczenia UIViewContentMode. 1 oznacza scaleAspectFit .

Ustaw button.imageView.contentMode w Storyboard

I wyrównanie przycisku w Inspektorze atrybutów :

Pełne wyrównanie przycisku

dimpiax
źródło
1

Nie mogę uzyskać rozwiązania używanego przez _imageView, ale mogę CGContextRefgo rozwiązać za pomocą a. Używa UIGraphicsGetCurrentContextdo pobrania currentContextRef i narysowania obrazu w currentContextRef, a następnie skaluje lub obraca obraz i tworzy nowy obraz. Ale to nie jest idealne.

kod:

-(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
źródło
1

Mam nadzieję, że to pomoże komuś innemu:

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill
Dasoga
źródło
0

od @JosephH

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

Michael Colonna
źródło
-1

Każdy UIButton ma swój własny ukryty widok UIImageView. Musimy więc ustawić tryb treści w sposób podany poniżej ...

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
emraz
źródło
-1

Zrzut ekranu w XCode 8

W lewym dolnym rogu zrzutu ekranu możesz zobaczyć właściwości rozciągania. Spróbuj ich użyć.

Harsh G.
źródło