web-dev-qa-db-fra.com

scale Image dans un UIButton à AspectFit?

Je souhaite ajouter une image à un bouton UIB et souhaite également adapter mon image à celle du bouton UIB (réduire la taille de l'image). S'il vous plaît, montrez-moi comment le faire.

C’est ce que j’ai essayé, mais ça ne marche pas:

  • Ajouter une image au bouton et utiliser setContentMode:
[self.itemImageButton setImage:stretchImage forState:UIControlStateNormal];
[self.itemImageButton setContentMode:UIViewContentModeScaleAspectFit];
  • Faire une "image étirée":
UIImage *stretchImage = [updatedItem.thumbnail stretchableImageWithLeftCapWidth:0 topCapHeight:0];
82
KONG

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 ne fera que perdre des cycles du processeur. 

C'est la catégorie que j'utilise pour redimensionner 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
gcamp

J'ai eu le même problème. Il suffit de définir le ContentMode de ImageView qui se trouve dans le UIButton.

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

J'espère que cela t'aides.

196
Dave

Aucune des réponses ici ne fonctionnait vraiment 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 Interface Builder.

 enter image description here

89
NAlexN

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

Rapide

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

Objectif c

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

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

41
Tanguy G.

J'ai eu des problèmes avec le redimensionnement proportionnel de l'image, donc la façon dont je l'ai corrigée utilisait des incrustations Edge.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
19
ninjaneer

En développant la réponse de Dave, vous pouvez définir la contentMode de la imageView du bouton dans IB, sans code, à l'aide des attributs d'exécution:

 enter image description here

  • 1 signifie UIViewContentModeScaleAspectFit,
  • 2 voudrait dire UIViewContentModeScaleAspectFill.
13
Ortwin Gentz

Cela peut maintenant être effectué 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.

enter image description here

13
capikaw

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

yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
8
Tulleb

La solution la plus propre consiste à utiliser Mise en page automatique . J'ai abaissé Priorité de résistance à la compression du contenu de ma 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é à merveille.

4
Rudolf Adamkovič

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

-(void)makeImageAspectFitForButton:(UIButton*)button{
    button.imageView.contentMode=UIViewContentModeScaleAspectFit;
    button.contentHorizontalAlignment=UIControlContentHorizontalAlignmentFill;
    button.contentVerticalAlignment=UIControlContentVerticalAlignmentFill;
}
4
Abedalkareem Omreyh

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

3
andrew

L’image d’arrière-plan peut en fait être réglée pour redimensionner l’aspect 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
Andy Poes

Pour Xamarin.iOS (C #):

    myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
    myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
    myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
0

1 - effacer le texte par défaut du bouton (important)

2 - régler l'alignement comme l'image 

3 - définir le mode de contenu comme image

 enter image description here

0
Hamid Reza Ansari

Swift 5.0

 myButton2.contentMode = .scaleAspectFit
 myButton2.contentHorizontalAlignment = .fill
 myButton2.contentVerticalAlignment = .fill
0
Qasim Mirza