Sono un po 'in ritardo a questa festa, ma penso di avere qualcosa di utile da aggiungere.
La risposta di Kekoa è ottima ma, come menziona RonLugge, può fare in modo che il pulsante non rispetti più sizeToFit
o, cosa ancora più importante, può fare in modo che il pulsante ritagli il contenuto quando è intrinsecamente dimensionato. Yikes!
Prima però
Una breve spiegazione di come credo imageEdgeInsets
e titleEdgeInsets
lavoro:
I documenti perimageEdgeInsets
hanno quanto segue da dire, in parte:
Utilizzare questa proprietà per ridimensionare e riposizionare il rettangolo di disegno effettivo per l'immagine del pulsante. È possibile specificare un valore diverso per ciascuno dei quattro inserti (in alto, a sinistra, in basso, a destra). Un valore positivo si restringe o inserisce quel bordo, avvicinandolo al centro del pulsante. Un valore negativo si espande, o supera, quel bordo.
Credo che questa documentazione sia stata scritta immaginando che il pulsante non abbia titolo, solo un'immagine. Ha molto più senso pensare in questo modo e si comporta come al UIEdgeInsets
solito. Fondamentalmente, la cornice dell'immagine (o il titolo, con titleEdgeInsets
) viene spostata verso l'interno per inserti positivi e verso l'esterno per gli inserti negativi.
OK, e allora?
Ci sto arrivando! Ecco cosa hai di default, impostando un'immagine e un titolo (il bordo del pulsante è verde solo per mostrare dove si trova):
Quando si desidera spaziare tra un'immagine e un titolo, senza causare la compressione di uno dei due, è necessario impostare quattro diversi inserti, due su ciascuna immagine e titolo. Questo perché non vuoi cambiare le dimensioni dei frame di quegli elementi, ma solo le loro posizioni. Quando inizi a pensare in questo modo, diventa evidente la modifica necessaria all'eccellente categoria di Kekoa:
@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
Ma aspetta , dici, quando lo faccio, ottengo questo:
O si! Ho dimenticato, i documenti mi hanno avvertito di questo. Dicono, in parte:
Questa proprietà viene utilizzata solo per posizionare l'immagine durante il layout. Il pulsante non utilizza questa proprietà per determinare intrinsicContentSize
e sizeThatFits:
.
Ma v'è una proprietà che può aiutare, e questo è contentEdgeInsets
. I documenti per questo dicono, in parte:
Il pulsante utilizza questa proprietà per determinare intrinsicContentSize
e sizeThatFits:
.
Suona bene. Quindi ottimizziamo ancora una volta la categoria:
@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
E cosa ottieni?
A me sembra un vincitore.
Lavorare in Swift e non vuoi assolutamente pensare? Ecco la versione finale dell'estensione in 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)
}
}