image à l'échelle dans un UIButton à AspectFit?

Je veux ajouter une image à un UIButton, et je veux aussi mettre à l'échelle mon image pour l'adapter à L'UIButton (rendre l'image plus petite). Veuillez me montrer comment le faire.

C'est ce que j'ai essayé, mais cela ne fonctionne pas:

  • Ajout d'une image au bouton et utilisation de setContentMode:
[self.itemImageButton setImage:stretchImage forState:UIControlStateNormal];
[self.itemImageButton setContentMode:UIViewContentModeScaleAspectFit];
  • Faire une "image extensible":
UIImage *stretchImage = [updatedItem.thumbnail stretchableImageWithLeftCapWidth:0 topCapHeight:0];
79
demandé sur Ortwin Gentz 2010-01-08 06:34:59

14 réponses

Si vous voulez vraiment redimensionner une image, Faites-Le, mais vous devez le redimensionner avant de l'utiliser. Le redimensionner au moment de l'exécution va juste perdre des cycles CPU.

C'est la catégorie que j'utilise pour mettre à l'échelle une image:

UIImage + Extra.h

@interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
@end;

UIImage + Extra.m

@implementation UIImage (Extras)

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {

UIImage *sourceImage = self;
UIImage *newImage = nil;

CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;

CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;

CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;

CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

if (!CGSizeEqualToSize(imageSize, targetSize)) {

        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor < heightFactor) 
                scaleFactor = widthFactor;
        else
                scaleFactor = heightFactor;

        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the image

        if (widthFactor < heightFactor) {
                thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
        } else if (widthFactor > heightFactor) {
                thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
}


// this is actually the interesting part:

UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0);

CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width  = scaledWidth;
thumbnailRect.size.height = scaledHeight;

[sourceImage drawInRect:thumbnailRect];

newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

if(newImage == nil) NSLog(@"could not scale image");


return newImage ;
}

@end

, Vous pouvez l'utiliser à la taille que vous voulez. Comme:

[self.itemImageButton setImage:[stretchImage imageByScalingProportionallyToSize:CGSizeMake(20,20)]];
27
répondu gcamp 2015-02-23 20:24:34

J'ai eu le même problème. Il suffit de définir le ContentMode de L'ImageView qui est à l'intérieur de L'UIButton.

[[self.itemImageButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[self.itemImageButton setImage:[UIImage imageNamed:stretchImage] forState:UIControlStateNormal];

J'espère que cela aide.

196
répondu Dave 2010-07-19 13:22:45

Aucune des réponses ici vraiment travaillé pour moi, j'ai résolu le problème avec le code suivant:

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

Vous pouvez également le faire dans le Générateur D'Interface.

entrez la description de l'image ici

86
répondu NAlexN 2016-03-01 00:51:14

Le moyen le plus simple de définir par programmation un imageView UIButton en mode aspect fit :

Swift

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

Objectif-C

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Note: Vous pouvez modifier .scaleAspectFit (UIViewContentModeScaleAspectFit) à .scaleAspectFill (UIViewContentModeScaleAspectFill) pour définir un aspect fill mode

35
répondu Tanguy G. 2017-09-07 12:18:05

J'ai eu des problèmes avec l'image ne pas redimensionner proportionnellement, donc la façon dont je l'ai corrigé utilisait des encarts de bord.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
18
répondu ninjaneer 2012-06-07 07:44:45

Cela peut maintenant être fait via les propriétés UIButton D'IB. La clé est de définir votre image comme arrière-plan, sinon cela ne fonctionnera pas.

entrez la description de l'image ici

13
répondu capikaw 2014-09-09 21:37:41

En développant la réponse de Dave, vous pouvez définir le {[0] } du bouton imageView tout dans IB, sans code, en utilisant les attributs D'exécution:

entrez la description de l'image ici

  • 1 signifie UIViewContentModeScaleAspectFit,
  • 2 signifierait UIViewContentModeScaleAspectFill.
12
répondu Ortwin Gentz 2016-03-03 14:56:33

Si vous voulez simplement réduire votre image de bouton:

yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
7
répondu Tulleb 2014-04-18 08:54:48

La solution La plus propre est d'utiliser Mise en page Automatique. J'ai abaissé la priorité de résistance à la Compression de contenu de mon UIButton et défini l'image (pas Image D'arrière-plan) via Interface Builder. Après cela, j'ai ajouté quelques contraintes qui définissent la taille de mon bouton (assez complexe dans mon cas) et cela a fonctionné comme un charme.

4
répondu Rudolf Adamkovič 2014-12-16 17:06:55

J'ai une méthode qui le fait pour moi . la méthode prend uibutton et fait correspondre l'aspect de l'image

-(void)makeImageAspectFitForButton:(UIButton*)button{
    button.imageView.contentMode=UIViewContentModeScaleAspectFit;
    button.contentHorizontalAlignment=UIControlContentHorizontalAlignmentFill;
    button.contentVerticalAlignment=UIControlContentVerticalAlignmentFill;
}
4
répondu Abedalkareem Omreyh 2016-02-29 05:10:50

Assurez-vous que vous avez défini la propriété image sur Image, mais pas sur L'arrière-plan

3
répondu andrew 2011-05-13 10:00:25

L'image D'arrière-plan peut en fait être définie sur le remplissage d'aspect à l'échelle assez facilement. Juste besoin de faire quelque chose comme ça dans une sous-classe de UIButton:

- (CGRect)backgroundRectForBounds:(CGRect)bounds
{
    // you'll need the original size of the image, you 
    // can save it from setBackgroundImage:forControlState
    return CGRectFitToFillRect(__original_image_frame_size__, bounds);
}

// Utility function, can be saved elsewhere
CGRect CGRectFitToFillRect( CGRect inRect, CGRect maxRect )
{
    CGFloat origRes = inRect.size.width / inRect.size.height;
    CGFloat newRes = maxRect.size.width / maxRect.size.height;

    CGRect retRect = maxRect;

    if (newRes < origRes)
    {
        retRect.size.width = inRect.size.width * maxRect.size.height / inRect.size.height;
        retRect.origin.x = roundf((maxRect.size.width - retRect.size.width) / 2);
    }
    else
    {
        retRect.size.height = inRect.size.height * maxRect.size.width / inRect.size.width;
        retRect.origin.y = roundf((maxRect.size.height - retRect.size.height) / 2);
    }

    return retRect;
}
2
répondu Andy Poes 2013-09-13 21:15:19

Pour Xamarin.iOS (C#):

    myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
    myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
    myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
0
répondu Maciek z Wrocławia 2016-10-25 07:38:36

Vous avez juste besoin de définir le mode de contenu de UIButton imageview pour trois événements. -

[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];

[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateHighlighted];

[cell.imgIcon setImage:[UIImage imageWithData:data] forState:UIControlStateSelected];

Nous avons du code pour trois événements bcoz tout en mettant en évidence ou en sélectionnant si la taille du bouton est carrée et que la taille de l'image est rectangle, elle affichera l'image carrée au moment de la mise en évidence ou de la sélection.

Je suis sûr que cela fonctionnera pour vous.

-1
répondu ruyamonis346 2012-09-11 11:16:14