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];
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)]];
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.
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.
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
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);
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.
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:
-
1
signifieUIViewContentModeScaleAspectFit
, -
2
signifieraitUIViewContentModeScaleAspectFill
.
Si vous voulez simplement réduire votre image de bouton:
yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
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.
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;
}
Assurez-vous que vous avez défini la propriété image sur Image, mais pas sur L'arrière-plan
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;
}
Pour Xamarin.iOS (C#):
myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
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.