web-dev-qa-db-fra.com

UIButton n'écoute pas le réglage du mode contenu?

firstButton est un UIButton de type Custom. Je mets par programme trois d'entre eux dans chaque cellule d'un tableau, ainsi:

[firstButton setImage:markImage forState:UIControlStateNormal];
[firstButton setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:firstButton];

Ailleurs, je le dis à clipToBounds. Ce que je reçois est un recadrage du carré central de l'image, plutôt qu'un rendu à l'échelle. J'ai essayé cela de nombreuses façons, y compris en définissant la propriété mode sur firstButton.imageView, qui ne semble pas non plus fonctionner.

85
Dan Ray

J'ai eu le même problème. Je vois que cette question est un peu ancienne, mais je souhaite fournir une réponse claire et correcte pour permettre à d'autres personnes (comme moi) de retrouver un moment où elles apparaîtront dans leurs résultats de recherche.

Il m'a fallu un peu de recherche et d'expérimentation, mais j'ai trouvé la solution. Définissez simplement le ContentMode de la ImageView "cachée" qui se trouve dans le UIButton.

[[firstButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[firstButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

Peut-être que c'est ce à quoi Dan Ray faisait allusion dans sa réponse acceptée, mais je suppose que non.

178
Dave

Si vous traitez avec l'image d'UIButton (par opposition à backgroundImage), définir le contentMode sur l'UIButton lui-même ou sur son imageView n'a aucun effet (malgré ce que disent d'autres réponses).

Vous pouvez également le faire à la place:

self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
self.button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

Ou redimensionnez votre image en conséquence. 

OU utilisez simplement un UIImageView (qui respecte correctement le contentMode) auquel est attaché un UITapGestureRecognizer ou un UIButton transparent dessus. 

62
Alfie Hanssen

Plutôt que de définir contentMode sur le bouton lui-même, vous souhaiterez définir les propriétés contentHorizontalAlignment et contentVerticalAlignment et (surtout) la contentMode pour le bouton imageView pour tout type de remplissage ou d'ajustement. Voici un exemple:

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

Bien entendu, vous pouvez également effectuer d'autres tâches, telles que l'alignement de l'image du bouton en haut du bouton. Si vous n'avez pas besoin de remplir ou d'ajuster l'aspect, vous pouvez simplement définir l'alignement lui-même:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

Dans Swift, vous voudrez utiliser:

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

Cela fonctionne pour toutes les versions d'iOS, y compris les dernières versions avec mise en page automatique (i.e. iOS 4 à iOS 11+).

40
Chris Nolet

Après quelques heures de confusion, voici comment j'ai fonctionné sous iOS 3.2. Comme Dusker l'a mentionné, utiliser setBackgroundImage au lieu de setImage a été efficace.

CGRect myButtonFrame = CGRectMake(0, 0, 250, 250);
UIImage *myButtonImage = [UIImage imageNamed:@"buttonImage"];

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];

[myButton setBackgroundImage:myButtonImage forState:UIControlStateNormal];
[myButton setFrame: myButtonFrame];
[myButton setContentMode: UIViewContentModeScaleAspectFit];
7
Pierre

La solution consiste à utiliser un UIImageView avec tous les beaux paramètres de mode contenu souhaités, puis à superposer un bouton personnalisé. Dumb que vous ne pouvez pas faire tout cela en même temps, mais il semble que vous ne pouvez pas.

6
Dan Ray

Trouvé un correctif pour cela. Définissez la propriété adjustsImageWhenHighlighted de UIButton sur NO.

  UIButton *b = [[UIButton alloc] initWithFrame:rect];
        [b setImage:image forState:UIControlStateNormal];
        [b.imageView setContentMode:UIViewContentModeScaleAspectFill];
        [b setAdjustsImageWhenHighlighted:NO];

J'espère que cela t'aides. N'hésitez pas à commenter ci-dessous, je donnerai suite à vos questions.

4
iOSDevSF

Seule solution qui a fonctionné pour moi:

[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
3
Tariq

Ma réponse est similaire à celle de Kuba. J'avais besoin que mon image soit programmée.

UIImage *image = [[UIImage alloc] initWithContentsOfFile:...];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill; //this is needed for some reason, won't work without it.
for(UIView *view in button.subviews) {
    view.contentMode = UIViewContentModeScaleAspectFill;
}
2
ninjaneer

Swift 3

self.firstButton.imageView?.contentMode = .scaleAspectFill
2
Vaibhav Saran

Je pense que nous avons ici un problème de constructeur d’interface simple: apparemment, l’IB ignore tout changement en mode contenu APRÈS que vous ayez défini la propriété image.

la solution est aussi simple: définissez le mode de contenu, supprimez les noms d'image précédemment définis (assurez-vous de le supprimer dans tous les états, par défaut, mis en surbrillance, etc.), puis entrez à nouveau les noms d'image souhaités dans tous les états souhaités - et voilà .

1
JohnPayne

Au lieu de setImage, essayez setBackgroundImage.

1
dusker

Je vous conseille également de consulter la propriété adjustsImageWhenHighlightedUIButton pour éviter les déformations étranges de l'image lorsque vous appuyez sur le bouton.

0
MonsieurDart

Si le bouton UIB ne semble pas écouter les paramètres de contrainte de disposition, vérifiez si les images sont plus grandes que la taille du bouton. Utilisez toujours les images @ 2x et @ 3x pour les résolutions de la rétine.

0
Totoro

En essayant de comprendre cela, ma méthode est devenue un peu plus compliquée avec le temps, et j'ai fini par classer UIButton en sous-classant et en remplaçant setHighlighted:

Pour moi, cela fonctionne simplement pour abaisser l'image alpha à 0,5, car ils sont sur un fond noir.

Cependant, cela ne fonctionne que si je commente [super setHighlighted:] (où il semble que le code d’extension d’image est en cours), ce qui ne semble pas être la bonne façon de résoudre ce problème ... fonctionne bien, cependant. Nous verrons comment ça se passe pendant que je continue à travailler dessus.

- (void)setHighlighted:(BOOL)highlight {
    if (highlight) {
        [self.imageView setAlpha:.5];
    }  else {
        [self.imageView setAlpha:1];        
    }

//    [super setHighlighted:highlight];
}
0
jankins

Si vous recherchez une réponse qui fonctionne dans iOS 6 et iOS 7 et dans le scénario:

Vous pouvez définir une image dans votre storyboard:

enter image description here

Et alors:

for(UIView* testId in self.subviews) {
    if([testId isKindOfClass:[UIImageView class]])
        [testId setContentMode:UIViewContentModeScaleAspectFill];
}
0
Jakub