345 votes

Comment mettre l'image à droite du texte dans un UIButton ?

Je ne veux pas utiliser de sous-vue si je peux l'éviter. Je veux une UIButton avec une image de fond, du texte et une image. Actuellement, lorsque je fais cela, l'image se trouve à gauche du texte. L'image de fond, le texte et l'image ont tous des états de surbrillance différents.

0 votes

Pour ajouter un autre "hack" à la liste croissante : vous pouvez définir l'attributTitle du bouton comme une chaîne attribuée contenant le titre du bouton, un espace et l'image (sous forme de NSTextAttachment). Il se peut que vous deviez modifier les limites de la pièce jointe pour qu'elle s'aligne comme vous le souhaitez (cf. stackoverflow.com/questions/26105803/ ).

610voto

Liau Jian Jie Points 5423

La solution la plus simple :

iOS 10 et plus, Swift :

button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

Avant iOS 10, Swift/Obj-C :

button.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.titleLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

iOS 9 et plus, Swift : (Recommandé)

button.semanticContentAttribute = .forceRightToLeft

10 votes

Je l'ai utilisé pour l'affichage du titre de la barre de navigation et il y a eu un problème. Tout va bien lorsqu'elle est chargée pour la première fois, mais lorsqu'on pousse un contrôleur de vue et qu'on l'ouvre, le titre est inversé.

0 votes

@WoominJoshPark Intéressant... Je peux seulement deviner que c'est parce que la transformation est animée en interne pour les animations pop de navigation.

0 votes

Je pense que dans le UIInterfaceBuilder vous devez construire le bouton retourné, pour le retourner par ce bout de code dans cette réponse.

335voto

Benjamin Points 21

Bien que certaines des réponses proposées soient très créatives et extrêmement astucieuses, la solution la plus simple est la suivante :

button.semanticContentAttribute = UIApplication.shared
    .userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft

C'est aussi simple que cela. En prime, l'image sera à gauche dans les localités de droite à gauche.

EDIT Comme la question a été posée à plusieurs reprises, voici ce que je propose. iOS 9 + .

0 votes

C'est une excellente idée. Elle n'existait pas lorsque la question a été posée pour la première fois, mais elle semble être la meilleure solution maintenant. L'avez-vous testé pour confirmer ?

0 votes

Oui, je l'ai utilisé plusieurs fois dans le code. Elle fonctionne comme prévu et ajoute la possibilité d'ajouter des sous-vues à un UIButton sans tous les problèmes de transformation qu'entraînerait la réponse de @Lindeman. :)

0 votes

Un autre avantage de cette solution est qu'elle peut être réalisée à partir du constructeur d'interface :)

305voto

Victor Rius Points 2430

MISE À JOUR POUR XCODE 9 (via Interface Builder)

Il y a un moyen plus facile à partir du Constructeur d'interface .

Sélectionnez le bouton UIB et sélectionnez cette option dans la vue Utilitaires > Sémantique :

left-to-right enter image description here C'est tout ! C'est simple et agréable !

OPTIONNEL - 2ème étape :

Si vous souhaitez ajuster l'espacement entre l'image et le titre, vous pouvez modifier l'élément suivant Image Inset ici :

enter image description here

J'espère que cela vous aidera !

2 votes

Dans Xcode 9.0 beta 5 (9M202q), vous ne voyez malheureusement le résultat qu'au moment de l'exécution - dans le storyboard, l'image de gauche est toujours affichée. Notez également qu'à cause de cela, il faut faire des essais et des erreurs pour définir les inserts corrects.

10 votes

S'il vous plaît, ne le faites pas de cette façon - cela casse la localisation pour les langues de droite à gauche.

177voto

einsteinx2 Points 6624

La sous-classification de UIButton est totalement inutile. Au lieu de cela, vous pouvez simplement définir une valeur d'insertion haute à gauche pour les insertions d'images, et une petite insertion à droite pour le titre. Quelque chose comme ceci :

button.imageEdgeInsets = UIEdgeInsetsMake(0., button.frame.size.width - (image.size.width + 15.), 0., 0.);
button.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., image.size.width);

3 votes

Cela a fonctionné, mais n'oubliez pas qu'aujourd'hui, avec autolayout, vous devez le faire sur viewDidAppear et non sur viewDidLoad.

94voto

jasongregori Points 3026

Je donne Inspire48 le mérite de celle-ci. En me basant sur sa suggestion et en regardant l'autre question, j'ai trouvé ceci. Sous-classe UIButton et surchargez ces méthodes.

@implementation UIButtonSubclass

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super imageRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) -  self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMinX(frame) - CGRectGetWidth([self imageRectForContentRect:contentRect]);
    return frame;
}

@end

3 votes

UIButton est un groupe de classes et ne doit pas être sous-classé.

51 votes

Ce n'est pas vrai, la documentation mentionne explicitement la sous-classification et fournit des méthodes que vous devez surcharger pour un comportement de mise en page personnalisé.

2 votes

developer.apple.com/library/ios/documentation/uikit/reference/ buttonWithType If you subclass UIButton, this method does not return an instance of your subclass. If you want to create an instance of a specific subclass, you must alloc/init the button directly y backgroundRectForBounds Les sous-classes qui fournissent des ornements d'arrière-plan personnalisés peuvent surcharger cette méthode et renvoyer un rectangle de délimitation modifié pour empêcher le bouton de se dessiner sur tout contenu personnalisé. ` Ni l'un ni l'autre ne mentionne ces méthodes spécifiques, mais je suppose que les sous-classes ne les gênent pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X