Wie skaliere ich die imageView eines UIButton?

80

Ich habe eine UIButton-Instanz mit dem Namen "button" mit einem Bild erstellt [UIButton setImage:forState:]. Der button.frame ist größer als das Bild.

Jetzt möchte ich das Bild dieser Schaltfläche verkleinern. Ich habe versucht button.imageView.frame, mich zu ändern , button.imageView.boundsund button.imageView.contentMode, aber alle scheinen unwirksam.

Kann mir jemand helfen UIButton, die Bildansicht von a zu skalieren?

Ich habe folgendes erstellt UIButton:

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

Ich habe versucht, das Bild folgendermaßen zu skalieren:

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

und das:

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

Antworten:

90

Für das Originalplakat habe ich folgende Lösung gefunden:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Dadurch kann Ihre Schaltfläche horizontal skaliert werden. Es gibt auch eine vertikale Einstellung.

Ich habe mehrere Stunden gebraucht, um das herauszufinden (die Benennung der Immobilie ist sehr unintuitiv), also dachte ich mir, ich würde es teilen.

Chris
quelle
gute sugggestion! Mein Problem bestand darin, das gestreckte Bild zu skalieren, um die Größe der linken Balkenschaltfläche abhängig vom Titel zu ändern.
Valerii Pavlov
1
Dies funktioniert, wird jedoch nicht außerhalb der Grenzen gezeichnet. Stellen Sie sich vor, Sie richten Text in einer Linie aus, bei der nichts über die Ränder hinausgeht. Sie erhalten also keinen Effekt wie UIViewContentModeScaleAspectFill (wobei ein Teil des Bildes beschnitten ist).
Hlung
66

Ich hatte ein ähnliches Problem, bei dem ich ein Hintergrundbild (eines mit Rand) und ein Bild (Flagge) für eine benutzerdefinierte Schaltfläche habe. Ich wollte, dass die Flagge verkleinert und in der Mitte ist. Ich habe versucht, das Attribut von imageView zu ändern, war jedoch nicht erfolgreich und habe dieses Bild gesehen.

Geben Sie hier die Bildbeschreibung ein

Während meiner Experimente habe ich versucht:

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

Ich habe das erwartete Ergebnis erzielt als:

Geben Sie hier die Bildbeschreibung ein

Hitesh Savaliya
quelle
41

Eine zusätzliche Möglichkeit zur Konfiguration in einer XIB-Datei. Sie können diese Option auswählen, wenn Sie möchten, dass Text oder Bild die vollständige Ausfüllung in UIButton skalieren. Mit Code wird es genauso sein.

UIButton *btn = [UIButton new];

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

Geben Sie hier die Bildbeschreibung ein

Linh Nguyen
quelle
Wenn Sie das Bild für UIButton perfekt strecken möchten, können Sie das Bildelement besser unterstützen und dieses Bild in Scheiben schneiden. developer.apple.com/library/ios/recipes/…
Linh Nguyen
War sich dieser Methode nicht einmal bewusst. Rock on
Michael McKenna
23

verwenden

button.contentMode = UIViewContentModeScaleToFill;

nicht

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Aktualisieren:

Wie @Chris kommentierte,

Damit dies für setImage: forState: funktioniert, müssen Sie die folgenden Schritte ausführen, um horizontal zu skalieren: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

pavelpanov
quelle
3
Dies funktioniert hervorragend in Kombination mit [button setBackgroundImage: forState:]. Vielen Dank.
Jason DeFontes
Beachten Sie genau, was Jason gesagt hat und Sie werden gut sein. Es funktioniert nicht für setImage: forState:
dpjanes
7
Damit dies für setImage: forState: funktioniert, müssen Sie die folgenden Schritte ausführen, um horizontal zu skalieren: 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
quelle
@EEE Danke. Aber es gibt 2 Probleme: 1. Meine Frage ist, die _imageView-Variable des UIButton zu verwenden, nicht die _backgroundView-Variable. Muss ich das mit backgroundView machen? 2. Die Funktion [UIImage stripableImageWithLeftCapWidth: topCapHeight:] kann das Bild nur vergrößern, aber nicht verkleinern. Trotzdem danke und Ihre Antwort löst meine andere Frage: Ich möchte einen Titel auf die Schaltfläche mit dem Bild dahinter zeichnen. Ich denke, das _backgroundImage kann mir helfen. Hat diese Frage eine andere bessere Antwort?
vcLwei
Ich sehe, was Sie versuchen, und das ist der Weg. Wenn Ihr Bild größer ist, ändern Sie die Größe mit einem Werkzeug, und alles, was Sie tun möchten, wird erledigt. Verschwenden Sie Ihre Zeit nicht mit_imageview. Übrigens, wenn Ihnen diese Antwort gefällt, können Sie sie abstimmen und akzeptieren
EEE
Sie können die Größe Ihres Bildes im Vorschauprogramm unter MacOS ändern. Öffnen Sie einfach die Bild- und Auswahlwerkzeuge -> Anpassen
EEE
@EEE Ja, ich kann die Größe meines Bildes mit einem Tool ändern. Aber in meiner Anwendung brauche ich manchmal auch das größere Bild, ich möchte nicht zwei ähnliche Bilder nur in der Größe unterscheiden, das auch Platz verschwenden. Eine andere Möglichkeit, meine Frage zu lösen, besteht darin, dass ich CGBitmapContext verwenden kann, um ein kleineres Bild zu erhalten. Ich denke, dieser Weg ist im Vergleich zur Verwendung von _imageview unpraktisch. Der Grund, warum ich nicht dafür gestimmt habe, ist, dass mein Ruf weniger als 15 ist, eigentlich möchte ich das wirklich tun. Vielen Dank!
vcLwei
10

Ich habe diese Lösung gefunden.

1) Unterklasse der folgenden Methoden von UIButton

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

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

Und es funktioniert gut.

Marcio
quelle
- (CGRect) backgroundRectForBounds: (CGRect) Grenzen für das Hintergrundbild.
Ricky
9

Seltsam, die einzige Kombination, die für mich (iOS 5.1) funktioniert hat, ist ...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

und

[button setImage:newImage forState:UIControlStateNormal];

Hlung
quelle
Ursprünglich habe ich verwendet: button.contentMode = UIViewContentModeScaleAspectFit; Jetzt muss ich auch button.imageView.contentMode = UIViewContentModeScaleAspectFit schreiben. Seitenverhältnis auf iPad 3 Retina zu halten
Enrico Detoma
7

Tun Sie es einfach (vom Design oder vom Code):

Vom Design

  1. Öffnen Sie Ihr xib OR Storyboard.
  2. Auswahlknopf
  3. Innerhalb des Attributinspektors (rechte Seite)> Wählen Sie im Abschnitt "Steuerung" die letzte vierte Option für Horizontal und Verisch aus.

[Für Punkt 3: Ändern Sie die horizontale und vertikale Ausrichtung auf UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

Aus dem Code

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
Sandip Patel - SM
quelle
5

So kann Ihr Problem gelöst werden:

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

 return resizedImage;
}
Huangkui
quelle
5

Von einem kleinen Test, den ich gerade nach dem Lesen hier gemacht habe, hängt davon ab, ob Sie setImage oder setBackgroundImage verwenden. Beide haben das gleiche Ergebnis erzielt und das Bild gestreckt

//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
quelle
Vielen
4
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
iomar
quelle
2

Dies funktioniert auch, da das backgroundImage automatisch skaliert

[button setBackgroundImage:image forState:UIControlStateNormal];

Harris
quelle
2

Storyboard

Sie müssen bestimmte Eigenschaft definieren in Runtime - Attribute von Inspektoren Identität - imageView.contentModel, wo Sie Wert relativ zu rawValuePosition von ENUM UIViewContentMode. 1 bedeutet scaleAspectFit .

Legen Sie button.imageView.contentMode im Storyboard fest

Und die Ausrichtung der Schaltfläche im Attributinspektor :

Volle Ausrichtung der Taste

Dimpiax
quelle
1

Ich kann keine Lösung von _imageView verwenden lassen, aber ich kann eine verwenden CGContextRef, um sie zu lösen. Es benutzt dieUIGraphicsGetCurrentContext das currentContextRef abgerufen und ein Bild in currentContextRef gezeichnet. Anschließend wird das Bild skaliert oder gedreht und ein neues Bild erstellt. Aber es ist nicht perfekt.

der Code:

-(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
quelle
1

Ich hoffe, das kann jemand anderem helfen:

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill
Dasoga
quelle
-1

Jeder UIButton hat eine eigene versteckte UIImageView. Also müssen wir den Inhaltsmodus wie folgt einstellen ...

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
Emraz
quelle
-1

Screenshot in XCode 8

Unten links im Screenshot sehen Sie die Dehnungseigenschaften. Versuchen Sie es mit diesen.

Harsh G.
quelle