Llego un poco tarde a esta fiesta, pero creo que tengo algo útil que agregar.
La respuesta de Kekoa es excelente, pero, como menciona RonLugge, puede hacer que el botón ya no respete sizeToFit
o, lo que es más importante, puede hacer que el botón recorte su contenido cuando tiene un tamaño intrínseco. ¡Ay!
Primero, sin embargo,
Una breve explicación de cómo creo imageEdgeInsets
y titleEdgeInsets
trabajo:
Los documentos paraimageEdgeInsets
tienen lo siguiente que decir, en parte:
Use esta propiedad para cambiar el tamaño y la posición del rectángulo de dibujo efectivo para la imagen del botón. Puede especificar un valor diferente para cada una de las cuatro inserciones (superior, izquierda, inferior, derecha). Un valor positivo reduce o inserta ese borde, acercándolo al centro del botón. Un valor negativo expande, o compensa, ese borde.
Creo que esta documentación fue escrita imaginando que el botón no tiene título, solo una imagen. Tiene mucho más sentido pensar de esta manera, y se comporta como UIEdgeInsets
suele hacerlo. Básicamente, el marco de la imagen (o el título, con titleEdgeInsets
) se mueve hacia adentro para inserciones positivas y hacia afuera para inserciones negativas.
¿OK y eso qué?
¡Estoy llegando! Esto es lo que tiene de manera predeterminada, configurando una imagen y un título (el borde del botón es verde solo para mostrar dónde está):
Cuando desee un espacio entre una imagen y un título, sin hacer que ninguno de los dos sea aplastado, debe establecer cuatro inserciones diferentes, dos en cada imagen y título. Esto se debe a que no desea cambiar el tamaño de los marcos de esos elementos, sino solo sus posiciones. Cuando comienzas a pensar de esta manera, el cambio necesario a la excelente categoría de Kekoa queda claro:
@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
Pero espera , dices, cuando hago eso, me sale esto:
¡Oh si! Olvidé, los documentos me advirtieron sobre esto. Dicen, en parte:
Esta propiedad se usa solo para posicionar la imagen durante el diseño. El botón no usa esta propiedad para determinar intrinsicContentSize
y sizeThatFits:
.
Pero no es una propiedad que ayuda lata, y eso es contentEdgeInsets
. Los documentos para eso dicen, en parte:
El botón usa esta propiedad para determinar intrinsicContentSize
y sizeThatFits:
.
Eso suena bien. Entonces, modifiquemos la categoría una vez más:
@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
Y que obtienes
Me parece un ganador.
¿Trabajas en Swift y no quieres pensar en absoluto? Aquí está la versión final de la extensión en 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)
}
}