279 votes

Aligner le texte et l’image sur UIButton avec imageEdgeInsets et titleEdgeInsets

Je voudrais placer une icône à gauche de la deux lignes de texte tel qu'il y a environ 2-3 pixels de l'espace entre l'image et le début du texte. Le contrôle lui-même est le Centre aligné horizontalement (à définir par le biais de l'Interface Builder)

Le bouton devrait ressembler à quelque chose comme ceci:

|                  |
|[Image] Add To    |
|        Favorites |

Je suis en train de configurer ce avec contentEdgeInset, imageEdgeInsets et titleEdgeInsets en vain. Je comprends qu'une valeur négative s'étend du bord tandis qu'une valeur positive réduit pour le déplacer plus près du centre.

J'ai essayé:

[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];

mais cela ne veut pas les afficher correctement. J'ai été modifier les valeurs, mais va de -5 à -10 sur la gauche en rentrant de la valeur n'apparaît pas à le déplacer dans la manière attendue. -10 sera scoot le texte tout le chemin vers la gauche, donc je m'attendais à -5 scoot à mi-chemin à partir de la gauche, mais il ne le fait pas.

Quelle est la logique derrière les encarts? Je ne suis pas familier avec l'image de placements et de terminologie.

J'ai utilisé ce DONC, la question comme une référence, mais quelque chose à propos de mes valeurs n'est pas droit. UIButton: comment faire pour centrer une image et d'un texte à l'aide de imageEdgeInsets et titleEdgeInsets?

456voto

Riley Points 1435

Je suis un peu en retard pour cette partie, mais je pense que j'ai quelque chose d'utile à ajouter.

Kekoa la réponse est grand, mais, comme RonLugge mentionne, il peut faire le bouton n'est plus respecter sizeToFit ou, plus important encore, peut causer le bouton pour le clip de son contenu lorsqu'elle est intrinsèquement de taille moyenne. Oups!

Mais d'abord,

Une brève explication de la façon dont, je crois, imageEdgeInsets et titleEdgeInsets travail:

Les docs pour imageEdgeInsets sont les suivantes-à-dire dans la partie:

Utilisez cette propriété pour redimensionner et repositionner le tracé effectif rectangle de l'image du bouton. Vous pouvez spécifier une valeur différente pour chacun des quatre encarts (en haut, à gauche, en bas, à droite). Une valeur positive se rétrécit, ou encarts, ce bord-le rapprocher du centre de la touche. Une valeur négative se développe, ou dilate, ce bord.

Je crois que cette documentation a été écrite en imaginant que le bouton n'a pas de titre, juste une image. Il fait beaucoup plus de sens de la pensée de cette façon, et se comporte comment UIEdgeInsets habituellement. En gros, l'image de l'image (ou le titre, titleEdgeInsets) est déplacé vers l'intérieur pour le positif encarts et vers l'extérieur pour les façades latérales.

OK, et alors?

Je vais y venir! Voici ce que vous avez par défaut, le réglage d'une image et un titre (le contour du bouton est vert juste pour montrer où il est):

where we start

Lorsque vous souhaitez que l'espacement entre une image et un titre, sans causer soit d'être écrasés, vous devez définir quatre différents encarts, deux sur chaque image et le titre. C'est parce que vous ne voulez pas changer les tailles de ces éléments " les cadres, mais seulement leurs positions. Lorsque vous commencez à penser de cette façon, le changement nécessaire à Kekoa la catégorie "excellent" devient claire:

@implementation UIButton(ImageTitleCentering)

-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing {
    CGFloat insetAmount = spacing / 2.0;
    self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
    self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
}

@end

Mais attendez, vous dites, quand je fais ça, j'obtiens ceci:

uh-oh, overlap

Oh que oui! J'ai oublié, les docs m'a averti à ce sujet. Ils disent, en partie:

Cette propriété est utilisée uniquement pour le positionnement de l'image lors de la présentation. Le bouton ne pas utiliser cette propriété pour déterminer intrinsicContentSize et sizeThatFits:.

Mais il est une propriété qui peut aider, et que l' contentEdgeInsets. Les docs pour dire que, dans le cadre:

Le bouton utilise cette propriété pour déterminer intrinsicContentSize et sizeThatFits:.

Qui sonne bien. Donc, nous allons modifier la catégorie, une fois de plus:

@implementation UIButton(ImageTitleCentering)

-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing {
    CGFloat insetAmount = spacing / 2.0;
    self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
    self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
    self.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
}

@end

Et qu'obtenez-vous?

it looks great!

Ressemble à un gagnant pour moi.

421voto

Kekoa Points 11545

Je suis d'accord la documentation sur imageEdgeInsets et titleEdgeInsets devrait être mieux, mais j'ai compris comment faire le bon positionnement sans recourir à l'essai et l'erreur.

L'idée générale est ici, à cette question, mais que si l'on voulait à la fois du texte et de l'image centrée. Nous ne voulons pas que l'image et le texte sera centré individuellement, nous voulons que l'image et le texte soit centré ensemble, comme une seule entité. C'est en fait ce que UIButton déjà le fait que nous avons simplement besoin de régler l'espacement.

CGFloat spacing = 10; // the amount of spacing to appear between image and title
tabBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
tabBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);

J'ai aussi contribué à faire de cette catégorie pour UIButton de sorte qu'il sera facile à utiliser:

UIButton+Position.h

@interface UIButton(ImageTitleCentering)

-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing;

@end

UIButton+Position.m

@implementation UIButton(ImageTitleCentering)

-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing {
    self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
    self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
}

@end

Alors maintenant, tout ce que j'ai à faire est de:

[button centerButtonAndImageWithSpacing:10];

Et j'ai ce dont j'ai besoin à chaque fois. Pas plus de jouer avec le bord des encarts manuellement.

39voto

Freeman Points 1725

Dans interface Builder. Sélectionnez le UIButton-> attributs inspecteur-> Edge = Title et modifier les incrustations de bord

31voto

Nishant Points 678

Vous pouvez éviter beaucoup d’ennuis en utilisant ce--

myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft ;
myButton.contentVerticalAlignment = UIControlContentHorizontalAlignmentCenter ;

Ceci alignera tous vos contenus automatiquement vers la gauche (ou partout où vous le souhaitez)

4voto

Zapko Points 1386

Pour ceux qui veulent comprendre le concept il y a un grand poster sur le thème. Avec un exemple de projet.

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