Je suis un peu en retard à cette fête, mais je pense que j'ai quelque chose d'utile à ajouter.
La réponse de Kekoa est excellente mais, comme le mentionne RonLugge, cela peut rendre le bouton plus respectueux sizeToFit
ou, plus important encore, provoquer le bouton pour couper son contenu lorsqu'il est intrinsèquement dimensionné. Oui!
Mais d'abord,
Une brève explication de la façon dont je crois imageEdgeInsets
et titleEdgeInsets
travaille:
Les documents pourimageEdgeInsets
ont ce qui suit à dire, en partie:
Utilisez cette propriété pour redimensionner et repositionner le rectangle de dessin efficace pour l'image du bouton. Vous pouvez spécifier une valeur différente pour chacun des quatre encarts (haut, gauche, bas, droite). Une valeur positive rétrécit ou insère ce bord, en le rapprochant du centre du bouton. Une valeur négative étend ou dépasse ce bord.
Je crois que cette documentation a été écrite en imaginant que le bouton n'a pas de titre, juste une image. Il est beaucoup plus logique de penser de cette façon et se comporte comme d' UIEdgeInsets
habitude. Fondamentalement, le cadre de l'image (ou le titre, avec titleEdgeInsets
) est déplacé vers l'intérieur pour les encarts positifs et vers l'extérieur pour les encarts négatifs.
Okay, alors quoi?
J'y arrive! Voici ce que vous avez par défaut, en définissant une image et un titre (la bordure du bouton est verte juste pour montrer où elle est):
Lorsque vous souhaitez un espacement entre une image et un titre, sans provoquer l’écrasement de l’un ou l’autre, vous devez définir quatre encarts différents, deux sur l’image et le titre. C'est parce que vous ne voulez pas changer la taille des cadres de ces éléments, mais simplement leur position. Lorsque vous commencez à penser de cette façon, le changement nécessaire à l'excellente catégorie de Kekoa devient clair:
@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, je reçois ceci:
Oh oui! J'ai oublié, les docs m'ont prévenu à ce sujet. Ils disent, en partie:
Cette propriété est utilisée uniquement pour positionner l'image pendant la mise en page. Le bouton n'utilise pas cette propriété pour déterminer intrinsicContentSize
et sizeThatFits:
.
Mais il y a une propriété qui peut aider, et c'est contentEdgeInsets
. Les documents pour cela disent, en partie:
Le bouton utilise cette propriété pour déterminer intrinsicContentSize
et sizeThatFits:
.
Ça sonne bien. Alors, ajustons 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?
On dirait un gagnant pour moi.
Vous travaillez chez Swift et vous ne voulez pas réfléchir du tout? Voici la version finale de l'extension dans Swift:
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}