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/ ).

80voto

Piotr Tomasik Points 2550

Il suffit de mettre à jour les inserts lorsque le titre est modifié. Vous devez compenser l'encart par un encart égal et opposé de l'autre côté.

[thebutton setTitle:title forState:UIControlStateNormal];
thebutton.titleEdgeInsets = UIEdgeInsetsMake(0, -thebutton.imageView.frame.size.width, 0, thebutton.imageView.frame.size.width);
thebutton.imageEdgeInsets = UIEdgeInsetsMake(0, thebutton.titleLabel.frame.size.width, 0, -thebutton.titleLabel.frame.size.width);

4 votes

Vous pourriez ajouter [thebutton.titleLabel sizeToFit]; avant. La largeur peut être nulle si vous n'avez pas déclenché de mise en page. Il en va de même pour la taille de l'image (utilisez simplement UIImage.size au lieu de la taille de l'imageView).

0 votes

@delrox : bon point. On peut utiliser titleWidth = [self.titleLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.bounds.size.height)].width; (ou, si vous craignez que le cadre du bouton ne soit pas encore établi, utilisez CGFLOAT_MAX pour la hauteur également) et imageWidth = self.currentImage.size.width;

1 votes

Fonctionne parfaitement sur viewDidLayoutSubviews

60voto

startupthekid Points 648

Toutes ces réponses, en date de janvier 2016, sont inutiles. Dans Interface Builder, définissez la sémantique de la vue sur . Force Right-to-Left ou si vous préférez la méthode programmatique, semanticContentAttribute = .forceRightToLeft Ainsi, l'image apparaîtra à droite de votre texte.

5 votes

Malheureusement, il ne supporte pas les ios plus anciens que 9. Mais c'est quand même une bonne réponse.

1 votes

J'ai le regret de vous annoncer que l'application de ce paramètre à un UIButton qui est ensuite utilisé pour UIBarButtonItem n'a entraîné aucun changement.

0 votes

Comme @Amelia l'a mentionné, cela ne fonctionne pas si vous appelez UIBarButtonItem(customView: button) mais cela fonctionnera si vous placez le bouton dans une vue vide.

53voto

zest Points 2098

Dans le constructeur d'interface, vous pouvez configurer les options Insets de bord pour UIButton, séparément chacune des trois parties : contenu, image, titre.

enter image description hereenter image description here

Xcode 8 :

enter image description here

3 votes

La meilleure réponse à mon avis à cette stackoverflow.com/a/39013315/1470374 ))

26voto

Jean-Baptiste Points 494

Mise à jour : Swift 3

class ButtonIconRight: UIButton {
    override func imageRect(forContentRect contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRect(forContentRect: contentRect)
        imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
    }

    override func titleRect(forContentRect contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRect(forContentRect: contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
        }
        return titleFrame
    }
}

Réponse originale pour Swift 2 :

Une solution qui gère tous les alignements horizontaux, avec un exemple de mise en œuvre en Swift. Il suffit de traduire en Objective-C si nécessaire.

class ButtonIconRight: UIButton {
    override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRectForContentRect(contentRect)
        imageFrame.origin.x = CGRectGetMaxX(super.titleRectForContentRect(contentRect)) - CGRectGetWidth(imageFrame)
        return imageFrame
    }

    override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRectForContentRect(contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
        }
        return titleFrame
    }
}

Il convient également de noter qu'il gère très bien les incrustations d'images et de titres.

Inspiré de la réponse de jasongregori ;)

1 votes

Cette solution a fonctionné pour moi, mais mon image avait besoin d'espace autour d'elle. J'ai donc ajouté le code suivant : self.contentEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0)

1 votes

J'aime cette méthode parce que vous pouvez ajouter @IBDesignable à la classe et la voir retournée au moment de la conception.

0 votes

Je préfère cette solution car elle fonctionne même lorsqu'elle est placée dans la barre de navigation.

20voto

Mark Hennings Points 16

J'ai décidé de ne pas utiliser l'affichage standard de l'image du bouton, car les solutions proposées pour le déplacer me semblaient peu pratiques. J'ai ainsi obtenu l'esthétique souhaitée, et il est intuitif de repositionner le bouton en modifiant les contraintes :

extension UIButton {
    func addRightIcon(image: UIImage) {
        let imageView = UIImageView(image: image)
        imageView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(imageView)

        let length = CGFloat(15)
        titleEdgeInsets.right += length

        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: self.titleLabel!.trailingAnchor, constant: 10),
            imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
            imageView.widthAnchor.constraint(equalToConstant: length),
            imageView.heightAnchor.constraint(equalToConstant: length)
        ])
    }
}

button with right arrow

0 votes

Il ne réagit pas aux tapotements, le texte s'estompe mais l'image ne disparaît pas.

0 votes

Vérifiez également votre extension sur les petits appareils.

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