UIButton: comment centrer une image et un texte en utilisant imageEdgeInsets et titleEdgeInsets?

si Je ne mets qu'une image dans un bouton et que je place les ensembles imageEdgeInsets plus près du haut, l'image reste centrée et tout fonctionne comme prévu:

[button setImage:image forState:UIControlStateNormal];
[button setImageEdgeInsets:UIEdgeInsetsMake(-15.0, 0.0, 0.0, 0.0)];

si Je ne mets qu'un texte dans un bouton et que je mets des ensembles de titres plus près du bas, le texte reste centré et tout fonctionne comme prévu:

[button setTitle:title forState:UIControlStateNormal];
[button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, -30, 0.0)];

mais, si je mets les 4 lignes ensemble, le texte interfère avec l'image et les deux ont perdu l'alignement du centre.

toutes mes images ont 30 pixels de largeur, et si je mets 30 dans le paramètre gauche de UIEdgeInsetMake pour setTitleEdgeInsets, le texte est à nouveau centré. Le problème est que l'image n'est jamais centrée parce qu'elle semble dépendre du bouton.taille titleLabel. J'ai déjà essayé de nombreux calculs avec la taille du bouton, la taille de l'image, la taille du label de titre et ne jamais obtenir les deux parfaitement centré.

Quelqu'un avait déjà le même problème?

148
demandé sur Pang 2010-03-16 02:35:00

24 réponses

pour ce que ça vaut, voici une solution générale pour positionner l'image centrée au-dessus du texte sans utiliser de nombres magiques. notez que le code suivant est périmé et vous devriez probablement utiliser une des versions mises à jour ci-dessous :

// the space between the image and text
CGFloat spacing = 6.0;

// lower the text and push it left so it appears centered 
//  below the image
CGSize imageSize = button.imageView.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
  0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);

// raise the image and push it right so it appears centered
//  above the text
CGSize titleSize = button.titleLabel.frame.size;
button.imageEdgeInsets = UIEdgeInsetsMake(
  - (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

la version suivante contient des changements au support iOS 7+ qui ont été recommandés dans les commentaires ci-dessous. Je n'ai pas testé ce code moi-même, donc je ne sais pas comment Eh bien, il fonctionne ou si elle se briserait si utilisé sous les versions précédentes de iOS.

// the space between the image and text
CGFloat spacing = 6.0;

// lower the text and push it left so it appears centered 
//  below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
  0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);

// raise the image and push it right so it appears centered
//  above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(
  - (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

// increase the content height to avoid clipping
CGFloat edgeOffset = fabsf(titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);

Swift version

extension UIButton {
  func alignVertical(spacing: CGFloat = 6.0) {
    guard let imageSize = self.imageView?.image?.size,
      let text = self.titleLabel?.text,
      let font = self.titleLabel?.font
      else { return }
    self.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0.0)
    let labelString = NSString(string: text)
    let titleSize = labelString.size(attributes: [NSFontAttributeName: font])
    self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: 0.0, bottom: 0.0, right: -titleSize.width)
    let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0;
    self.contentEdgeInsets = UIEdgeInsets(top: edgeOffset, left: 0.0, bottom: edgeOffset, right: 0.0)
  }
}
394
répondu Jesse Crossen 2017-05-11 04:01:45

trouvé comment.

tout d'abord, configurer le texte de titleLabel (en raison de styles, I. e, gras, italique, etc.). Ensuite, utilisez setTitleEdgeInsets en considérant la largeur de votre image:

[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitle:title forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont boldSystemFontOfSize:10.0]];

// Left inset is the negative of image width.
[button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, -image.size.width, -25.0, 0.0)]; 

après cela, utilisez setTitleEdgeInsets en considérant la largeur des limites du texte:

[button setImage:image forState:UIControlStateNormal];

// Right inset is the negative of text bounds width.
[button setImageEdgeInsets:UIEdgeInsetsMake(-15.0, 0.0, 0.0, -button.titleLabel.bounds.size.width)];

Maintenant, l'image et le texte sera centré (dans cet exemple, l'image s'affiche au-dessus du texte).

santé.

58
répondu reinaldoluckman 2018-03-29 07:10:30

vous pouvez le faire avec cette extension Swift, qui était basée en partie sur la réponse de Jesse Crossen:

extension UIButton {
  func centerLabelVerticallyWithPadding(spacing:CGFloat) {
    // update positioning of image and title
    let imageSize = self.imageView.frame.size
    self.titleEdgeInsets = UIEdgeInsets(top:0,
                                        left:-imageSize.width,
                                        bottom:-(imageSize.height + spacing),
                                        right:0)
    let titleSize = self.titleLabel.frame.size
    self.imageEdgeInsets = UIEdgeInsets(top:-(titleSize.height + spacing),
                                        left:0,
                                        bottom: 0,
                                        right:-titleSize.width)

    // reset contentInset, so intrinsicContentSize() is still accurate
    let trueContentSize = CGRectUnion(self.titleLabel.frame, self.imageView.frame).size
    let oldContentSize = self.intrinsicContentSize()
    let heightDelta = trueContentSize.height - oldContentSize.height
    let widthDelta = trueContentSize.width - oldContentSize.width
    self.contentEdgeInsets = UIEdgeInsets(top:heightDelta/2.0,
                                          left:widthDelta/2.0,
                                          bottom:heightDelta/2.0,
                                          right:widthDelta/2.0)
  }
}

définit une fonction centerLabelVerticallyWithPadding qui définit le titre et l'image insète de manière appropriée.

il définit également les ensembles de contenu, qui je crois est nécessaire pour s'assurer que intrinsicContentSize fonctionne toujours correctement, qui devrait utiliser la mise en page automatique.

je crois que toutes les solutions qui sous-classe UIButton sont techniquement illégitime, puisque vous n'êtes pas censé classer les commandes UIKit. C'est-à-dire: en théorie, ils pourraient casser dans de futures versions.

20
répondu algal 2014-06-18 21:11:33

modifier: mis à jour pour Swift 3

dans le cas où vous êtes à la recherche D'une solution rapide de la réponse de Jesse Crossen, vous pouvez ajouter ceci à une sous-classe de UIButton:

override func layoutSubviews() {

    let spacing: CGFloat = 6.0

    // lower the text and push it left so it appears centered
    //  below the image
    var titleEdgeInsets = UIEdgeInsets.zero
    if let image = self.imageView?.image {
        titleEdgeInsets.left = -image.size.width
        titleEdgeInsets.bottom = -(image.size.height + spacing)
    }
    self.titleEdgeInsets = titleEdgeInsets

    // raise the image and push it right so it appears centered
    //  above the text
    var imageEdgeInsets = UIEdgeInsets.zero
    if let text = self.titleLabel?.text, let font = self.titleLabel?.font {
        let attributes = [NSFontAttributeName: font]
        let titleSize = text.size(attributes: attributes)
        imageEdgeInsets.top = -(titleSize.height + spacing)
        imageEdgeInsets.right = -titleSize.width
    }
    self.imageEdgeInsets = imageEdgeInsets

    super.layoutSubviews()
}
12
répondu Thomas Verbeek 2017-04-07 04:41:49

il y a quelques bons exemples ici, mais je n'ai pas pu faire que cela fonctionne dans tous les cas quand il s'agit aussi de plusieurs lignes de texte (text wrapping). Pour que cela fonctionne, j'ai combiné quelques techniques:

  1. j'ai utilisé L'exemple de Jesse Crossen ci-dessus. Cependant, j'ai fixé une hauteur de texte issue et j'ai ajouté la possibilité de spécifier une marge de texte horizontale. La marge est utile pour permettre au texte de s'enrouler pour ne pas frapper le bord de la bouton:

    // the space between the image and text
    CGFloat spacing = 10.0;
    float   textMargin = 6;
    
    // get the size of the elements here for readability
    CGSize  imageSize   = picImage.size;
    CGSize  titleSize   = button.titleLabel.frame.size;
    CGFloat totalHeight = (imageSize.height + titleSize.height + spacing);      // get the height they will take up as a unit
    
    // lower the text and push it left to center it
    button.titleEdgeInsets = UIEdgeInsetsMake( 0.0, -imageSize.width +textMargin, - (totalHeight - titleSize.height), +textMargin );   // top, left, bottom, right
    
    // the text width might have changed (in case it was shortened before due to 
    // lack of space and isn't anymore now), so we get the frame size again
    titleSize = button.titleLabel.bounds.size;
    
    button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0.0, 0.0, -titleSize.width );     // top, left, bottom, right        
    
  2. assurez-vous de configurer l'étiquette de texte pour envelopper

    button.titleLabel.numberOfLines = 2; 
    button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
    button.titleLabel.textAlignment = UITextAlignmentCenter;
    
  3. cela va surtout fonctionner maintenant. Cependant, j'ai eu quelques boutons qui ne rendraient pas leur image correctement. L'image a été déplacée vers la droite ou vers la gauche (elle n'était pas centrée). J'ai donc utilisé une technique de mise en page UIButton pour forcer l'imageView à être centrée.

    @interface CategoryButton : UIButton
    @end
    
    @implementation CategoryButton
    
    - (void)layoutSubviews
    {
        // Allow default layout, then center imageView
        [super layoutSubviews];
    
        UIImageView *imageView = [self imageView];
        CGRect imageFrame = imageView.frame;
        imageFrame.origin.x = (int)((self.frame.size.width - imageFrame.size.width)/ 2);
        imageView.frame = imageFrame;
    }
    @end
    
9
répondu Tod Cunningham 2012-02-27 18:38:45

j'ai fait une méthode pour la réponse de @TodCunningham

 -(void) AlignTextAndImageOfButton:(UIButton *)button
 {
   CGFloat spacing = 2; // the amount of spacing to appear between image and title
   button.imageView.backgroundColor=[UIColor clearColor];
   button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
   button.titleLabel.textAlignment = UITextAlignmentCenter;
   // get the size of the elements here for readability
   CGSize imageSize = button.imageView.frame.size;
   CGSize titleSize = button.titleLabel.frame.size;

  // lower the text and push it left to center it
  button.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height   + spacing), 0.0);

  // the text width might have changed (in case it was shortened before due to 
  // lack of space and isn't anymore now), so we get the frame size again
   titleSize = button.titleLabel.frame.size;

  // raise the image and push it right to center it
  button.imageEdgeInsets = UIEdgeInsetsMake(- (titleSize.height + spacing), 0.0, 0.0, -     titleSize.width);
 }
9
répondu Bekir Onat Akin 2012-04-28 11:38:33

ne combattez pas le système. Si vos layouts deviennent trop complexes pour être gérés en utilisant Interface Builder + peut - être un code de configuration simple, faites les layouts manuellement d'une manière plus simple en utilisant layoutSubviews - c'est à ça que ça sert! Tout le reste sera des piratages.

créez une sous-classe UIButton et outrepassez sa méthode layoutSubviews pour aligner votre texte et votre image de façon programmatique. Ou utilisez quelque chose comme https://github.com/nickpaulson/BlockKit/blob/master/Source/UIView-BKAdditions.h donc vous pouvez implémenter layoutSubviews en utilisant un bloc.

6
répondu Steven Kramer 2012-03-01 14:06:07

Sous-Classe UIButton

- (void)layoutSubviews {
    [super layoutSubviews];
    CGFloat spacing = 6.0;
    CGSize imageSize = self.imageView.image.size;
    CGSize titleSize = [self.titleLabel sizeThatFits:CGSizeMake(self.frame.size.width, self.frame.size.height - (imageSize.height + spacing))];
    self.imageView.frame = CGRectMake((self.frame.size.width - imageSize.width)/2, (self.frame.size.height - (imageSize.height+spacing+titleSize.height))/2, imageSize.width, imageSize.height);
    self.titleLabel.frame = CGRectMake((self.frame.size.width - titleSize.width)/2, CGRectGetMaxY(self.imageView.frame)+spacing, titleSize.width, titleSize.height);
}
5
répondu Alex 2014-07-23 14:12:24

rien de mal avec les autres réponses, cependant je voulais juste noter que le même comportement peut être accompli visuellement dans Xcode en utilisant des lignes de code zéro. Cette solution est utile si vous n'avez pas besoin d'une valeur calculée ou si vous construisez avec un storyboard/xib (sinon d'autres solutions s'appliquent).

Note-je comprends que la question de L'OP est une question nécessitant un code. Je ne fais que fournir cette réponse pour être complète et comme alternative logique pour ceux qui utilisent storyboards / xibs.

pour modifier l'espacement sur l'image, le titre et les vues de contenu d'un bouton en utilisant les inserts de bord, vous pouvez sélectionner le bouton/contrôle et ouvrir l'Inspecteur des attributs. Faites défiler vers le bas vers le milieu de l'inspecteur et trouvez la section pour les inserts de bord.

edge-insets

on peut également accéder et modifier les insets de bord spécifiques pour le titre, l'image ou la vue de contenu .

menu-options

5
répondu Tommie C. 2015-05-06 18:06:57

extension UIButton avec Swift 3+ syntaxe:

extension UIButton {
    func alignImageAndTitleVertically(padding: CGFloat = 6.0) {
        let imageSize: CGSize = imageView!.image!.size
        titleEdgeInsets = UIEdgeInsetsMake(0.0, -imageSize.width, -(imageSize.height + padding), 0.0)
        let labelString = NSString(string: titleLabel!.text!)
        let titleSize = labelString.size(attributes: [NSFontAttributeName: titleLabel!.font])
        self.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + padding), 0.0, 0.0, -titleSize.width)
        let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0;
        self.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0)
    }
}

réponse originale: https://stackoverflow.com/a/7199529/3659227

4
répondu Maverick 2018-05-09 10:17:16

juste un changement mineur à la réponse de Jesse Crossen qui l'a fait fonctionner parfaitement pour moi:

au lieu de:

CGSize titleSize = button.titleLabel.frame.size;

j'ai utilisé ceci:

CGSize titleSize = [button.titleLabel.text sizeWithAttributes: @{NSFontAttributeName:button.titleLabel.font}];
3
répondu Cesar 2014-09-22 12:58:41

avec ce morceau de code, vous obtiendrez quelque chose comme ceci title and image alignment

extension UIButton {
    func alignTextUnderImage() {
        guard let imageView = imageView else {
                return
        }
        self.contentVerticalAlignment = .Top
        self.contentHorizontalAlignment = .Center
        let imageLeftOffset = (CGRectGetWidth(self.bounds) - CGRectGetWidth(imageView.bounds)) / 2//put image in center
        let titleTopOffset = CGRectGetHeight(imageView.bounds) + 5
        self.imageEdgeInsets = UIEdgeInsetsMake(0, imageLeftOffset, 0, 0)
        self.titleEdgeInsets = UIEdgeInsetsMake(titleTopOffset, -CGRectGetWidth(imageView.bounds), 0, 0)
    }
}
3
répondu Bohdan Savych 2016-07-04 08:55:03

en utilisant button.titleLabel.frame.size.width ne fonctionne que si l'étiquette est suffisamment courte pour ne pas être tronquée. Quand le texte de l'étiquette est tronqué, le positionnement ne fonctionne pas. La prise de

CGSize titleSize = [[[button titleLabel] text] sizeWithFont:[[button titleLabel] font]];

fonctionne pour moi, même lorsque le texte de l'étiquette est tronqué.

3
répondu dezember 2017-04-07 07:36:30

j'ai regardé les réponses existantes, mais j'ai aussi trouvé que le réglage du cadre de bouton est une première étape importante.

Voici une fonction que j'utilise qui prend soin de ceci:

const CGFloat kImageTopOffset   = -15;
const CGFloat kTextBottomOffset = -25;

+ (void) centerButtonImageTopAndTextBottom: (UIButton*)         button 
                                     frame: (CGRect)            buttonFrame
                                      text: (NSString*)         textString
                                 textColor: (UIColor*)          textColor
                                      font: (UIFont*)           textFont
                                     image: (UIImage*)          image
                                  forState: (UIControlState)    buttonState
{
    button.frame = buttonFrame;

    [button setTitleColor: (UIColor*)       textColor
                 forState: (UIControlState) buttonState];

    [button setTitle: (NSString*) textString
            forState: (UIControlState) buttonState ];


    [button.titleLabel setFont: (UIFont*) textFont ];

    [button setTitleEdgeInsets: UIEdgeInsetsMake( 0.0, -image.size.width, kTextBottomOffset,  0.0)]; 

    [button setImage: (UIImage*)       image 
            forState: (UIControlState) buttonState ];

    [button setImageEdgeInsets: UIEdgeInsetsMake( kImageTopOffset, 0.0, 0.0,- button.titleLabel.bounds.size.width)];
}
2
répondu Bamaco 2012-02-01 16:19:41

ou vous pouvez juste utiliser cette catégorie:

@interface UIButton (VerticalLayout)  

- (void)centerVerticallyWithPadding:(float)padding;  
- (void)centerVertically;  

@end  


@implementation UIButton (VerticalLayout)  

- (void)centerVerticallyWithPadding:(float)padding 
{      
    CGSize imageSize = self.imageView.frame.size;  
    CGSize titleSize = self.titleLabel.frame.size;  

    CGFloat totalHeight = (imageSize.height + titleSize.height + padding);  

    self.imageEdgeInsets = UIEdgeInsetsMake(- (totalHeight - imageSize.height),
                                            0.0f,
                                            0.0f,
                                            - titleSize.width);

    self.titleEdgeInsets = UIEdgeInsetsMake(0.0f,
                                            - imageSize.width,
                                            - (totalHeight - titleSize.height),
                                            0.0f);

}


- (void)centerVertically
{  
    const CGFloat kDefaultPadding = 6.0f;

    [self centerVerticallyWithPadding:kDefaultPadding];  
}  


@end
2
répondu RaffAl 2014-03-24 22:07:00

mon cas d'utilisation a rendu les insets ingérables:

  1. image de fond sur le bouton reste cohérente
  2. modifications dynamiques du texte et de l'image lorsque la longueur de la chaîne et la taille de l'image varient

C'est ce que j'ai fini par faire et je suis assez heureux avec elle:

  • " créez le bouton sur le storyboard avec une image de fond (cercle rond avec flou et couleur).

  • Déclarer une UIImageView dans ma classe:

    @implementation BlahViewController {
        UIImageView *_imageView;
    }
    
  • Créer une image instance de vue sur init:

    -(id)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self) {
            _imageView = [[UIImageView alloc] initWithCoder:aDecoder];
         }
         return self;
     }
    
  • dans viewDidLoad ajouter une nouvelle couche au bouton pour notre vue d'image et régler l'alignement du texte:

    [self.btn addSubview:_imageView];
    [self.btn.titleLabel setTextAlignment:NSTextAlignmentCenter];
    
  • dans le bouton méthode de clic ajouter mon image de superposition choisie à la vue d'image, la taille de ajustez l'image et le centre dans le bouton mais déplacez-le vers le haut 15 de sorte que je puisse mettre le texte offset ci-dessous:

    [_imageView setImage:[UIImage imageNamed:@"blahImageBlah]];
    [_imageView sizeToFit];
    _imageView.center = CGPointMake(ceilf(self.btn.bounds.size.width / 2.0f),
             ceilf((self.btn.bounds.size.height / 2.0f) - 15));
    [self.btn setTitle:@"Some new text" forState:UIControlStateNormal];
    

Note: ceilf() est important pour s'assurer qu'il est sur une limite de pixel pour la qualité d'image.

1
répondu Oliver Dungey 2014-07-02 17:57:18

mise à jour de la réponse de Jesse Crossen pour Swift 4 :

extension UIButton {
    func alignVertical(spacing: CGFloat = 6.0) {
        guard let imageSize = self.imageView?.image?.size,
            let text = self.titleLabel?.text,
            let font = self.titleLabel?.font
            else { return }
        self.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0.0)
        let labelString = NSString(string: text)
        let titleSize = labelString.size(withAttributes: [kCTFontAttributeName as NSAttributedStringKey: font])
        self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: 0.0, bottom: 0.0, right: -titleSize.width)
        let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0;
        self.contentEdgeInsets = UIEdgeInsets(top: edgeOffset, left: 0.0, bottom: edgeOffset, right: 0.0)
    }
}

utiliser cette voie:

override func viewDidLayoutSubviews() {
    button.alignVertical()
}
1
répondu DocPllana 2018-06-15 15:42:51

en supposant que vous voulez que le texte et l'image soient centrés horizontalement, image au-dessus du texte: Centrer le texte de l'interface builder et Ajouter un inset supérieur (faire de la place pour l'image). (laisser le médaillon de gauche à 0). Utilisez interface builder pour choisir l'image - sa position actuelle sera définie à partir du code, alors ne vous inquiétez pas que les choses ne seront pas bien dans IB. Contrairement aux autres réponses ci-dessus, cela fonctionne en fait sur toutes les versions iOS actuellement supportées (5,6 et 7).

en code, juste après avoir saisi l'image, supprimez L'ImageView du bouton (en positionnant l'image du bouton à null) (cela centrera automatiquement le texte, enveloppé si nécessaire). Puis instanciez votre propre ImageView avec la même taille de cadre et l'image et positionnez-la au milieu.

de cette façon, vous pouvez toujours choisir l'image de interface builder (bien qu'il ne sera pas aligné en IB comme dans simulateur, mais encore une fois, d'autres solutions ne sont pas compatibles à travers tous les ios pris en charge versions)

0
répondu Radu Simionescu 2014-04-04 22:37:58

j'avais du mal à le faire parce que je ne pouvais pas obtenir la taille de l'image et la largeur du texte sur le constructeur de ma vue. Deux changements mineurs sur la réponse de Jesse travaillé pour moi:

CGFloat spacing = 3;
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - image.size.width, - (image.size.height + spacing), 0.0);
CGSize titleSize = [name sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}];
self.imageEdgeInsets = UIEdgeInsetsMake(- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

Le changement sont:

  • utilisant [NSString sizeWithAttributes] pour obtenir la largeur du texte;
  • obtenir la taille de l'image directement sur le UIImage au lieu de UIImageView
0
répondu saulobrito 2017-05-23 11:47:25

cela fonctionne bien pour moi, pour plusieurs boutons, avec une largeur d'image différente et une longueur de titre différente:

sous-classe UIButton

override func layoutSubviews() {
    super.layoutSubviews()

    if let image = imageView?.image {

        let margin = 30 - image.size.width / 2
        let titleRect = titleRectForContentRect(bounds)
        let titleOffset = (bounds.width - titleRect.width - image.size.width - margin) / 2


        contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
            imageEdgeInsets = UIEdgeInsetsMake(0, margin, 0, 0)
            titleEdgeInsets = UIEdgeInsetsMake(0, (bounds.width - titleRect.width -  image.size.width - margin) / 2, 0, 0)
    }

}
0
répondu Rémy Virin 2015-09-25 09:41:07

fonctionne très bien pour la taille du bouton 80x80 pixels.

[self.leftButton setImageEdgeInsets:UIEdgeInsetsMake(0, 10.0, 20.0, 10.0)];    
[self.leftButton setTitleEdgeInsets:UIEdgeInsetsMake(60, -75.0, 0.0, 0.0)];
0
répondu BADRI 2015-12-07 11:16:28

j'ai fait quelques ajustements pour faire l'image alignée au centre horizontal:

// the space between the image and text
        let spacing = CGFloat(36.0);

        // lower the text and push it left so it appears centered
        //  below the image
        let imageSize = tutorialButton.imageView!.frame.size;
        tutorialButton.titleEdgeInsets = UIEdgeInsetsMake(
            0, -CGFloat(imageSize.width), -CGFloat(imageSize.height + spacing), 0.0);

        // raise the image and push it right so it appears centered
        //  above the text
        let titleSize = tutorialButton.titleLabel!.frame.size;
        tutorialButton.imageEdgeInsets = UIEdgeInsetsMake(
            -CGFloat(titleSize.height + spacing), CGFloat((tutorialButton.frame.width - imageSize.width) / 2), 0.0, -CGFloat(titleSize.width));
0
répondu Nguyễn Thanh Khiêm 2015-12-16 03:18:53

est-il obligatoire d'avoir recours à bord des encarts? Si ce n'est pas le cas, vous pouvez essayer de positionner le respect de center parent view

extension UIButton 
{
    func centerImageAndTextVerticaAlignment(spacing: CGFloat) 
    {
        var titlePoint : CGPoint = convertPoint(center, fromView:superview)
        var imageViewPoint : CGPoint = convertPoint(center, fromView:superview)
        titlePoint.y += ((titleLabel?.size.height)! + spacing)/2
        imageViewPoint.y -= ((imageView?.size.height)! + spacing)/2
        titleLabel?.center = titlePoint
        imageView?.center = imageViewPoint

    }
}
0
répondu Rodrigo Birriel 2016-11-10 15:53:55

vous devez déplacer l'image à droite par la largeur du texte. Ensuite, déplacez le texte à gauche par la largeur de l'image.

UIEdgeInsets imageEdgeInsets = self.remoteCommandsButtonLights.imageEdgeInsets;
imageEdgeInsets.left = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:[button.titleLabel font]}].width;
imageEdgeInsets.bottom = 14.0;
button.imageEdgeInsets = imageEdgeInsets;

UIEdgeInsets titleEdgeInsets = self.remoteCommandsButtonLights.titleEdgeInsets;
titleEdgeInsets.left = -button.currentImage.size.width;
titleEdgeInsets.top = 20.0;
button.titleEdgeInsets = titleEdgeInsets;

ajuster ensuite les insets supérieur et inférieur pour ajuster l'axe des ordonnées. Ceci pourrait probablement être fait programmatiquement aussi bien, mais devrait être constant pour votre taille d'image. Alors que les insets x-axis devront changer en fonction de la taille de l'étiquette de texte dans chaque bouton.

0
répondu pkamb 2017-06-26 23:48:16