¿Cómo se agrega texto multilínea a un UIButton?

Tengo el siguiente código…

UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds]; buttonLabel.text = @"Long text string"; [targetButton addSubview:buttonLabel]; [targetButton bringSubviewToFront:buttonLabel]; 

… la idea es que puedo tener texto de varias líneas para el botón, pero el texto siempre está oscurecido por la imagen de fondo del UIButton. Una llamada de registro para mostrar las subvistas del botón muestra que se ha agregado UILabel, pero el texto en sí no se puede ver. ¿Es esto un error en UIButton o estoy haciendo algo mal?

Para iOS 6 y superior, use lo siguiente para permitir líneas múltiples:

 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; // you probably want to center it button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to [button setTitle: @"Line1\nLine2" forState: UIControlStateNormal]; 

Para iOS 5 y siguientes, utiliza lo siguiente para permitir líneas múltiples:

 button.titleLabel.lineBreakMode = UILineBreakModeWordWrap; // you probably want to center it button.titleLabel.textAlignment = UITextAlignmentCenter; [button setTitle: @"Line1\nLine2" forState: UIControlStateNormal]; 

2017, para iOS9 adelante ,

En general, solo haz estas dos cosas:

  1. elige “Texto Atribuido”
  2. en la ventana emergente “Salto de línea”, seleccione “Ajustar palabra”

La respuesta seleccionada es correcta, pero si prefiere hacer este tipo de cosas en Interface Builder, puede hacer esto:

Foto

Para iOS 6:

 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; button.titleLabel.textAlignment = NSTextAlignmentCenter; 

Como

 UILineBreakModeWordWrap and UITextAlignmentCenter 

están en desuso en IOS 6 en adelante.

Si desea agregar un botón con el título centrado en varias líneas, establezca las configuraciones de su Interface Builder para el botón:

[ aquí ]

Para replantear la sugerencia de Roger Nolan, pero con un código explícito, esta es la solución general:

 button.titleLabel?.numberOfLines = 0 

SWIFT 3

 button.titleLabel?.lineBreakMode = .byWordWrapping button.titleLabel?.textAlignment = .center button.setTitle("Button\nTitle",for: .normal) 

Hay una manera mucho más fácil:

 someButton.lineBreakMode = UILineBreakModeWordWrap; 

(Editar para iOS 3 y posteriores 🙂

 someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap; 

A la izquierda alinear en iOS7 con autolayout:

 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; button.titleLabel.textAlignment = NSTextAlignmentLeft; button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 

En primer lugar, debe tener en cuenta que UIButton ya tiene un UILabel dentro. Puede configurarlo usando –setTitle:forState:

El problema con su ejemplo es que debe establecer la propiedad numberOfLines de UILabel en un valor distinto a su valor predeterminado de 1. También debe revisar la propiedad lineBreakMode .

Para aquellos que están utilizando el guión gráfico de Xcode 4, puedes hacer clic en el botón, y en el panel de Utilidades del lado derecho debajo de Atributos Inspector, verás una opción para Salto de línea. Elige Word Wrap, y deberías estar listo para continuar.

Las respuestas aquí le dicen cómo lograr el título del botón multilínea programáticamente.

Solo quería agregar que si está usando storyboards, puede escribir [Ctrl + Enter] para forzar una nueva línea en el campo de título de un botón.

HTH

En cuanto a la idea de Brent de poner el título UILabel como punto de vista de hermanos, no me parece una muy buena idea. Sigo pensando en problemas de interacción con UILabel debido a que sus eventos táctiles no pasan por la vista de UIButton.

Por otro lado, con una UILabel como subvista del UIButton, estoy bastante cómodo sabiendo que los eventos táctiles siempre se propagarán a la supervista de UILabel.

Tomé este enfoque y no noté ninguno de los problemas reportados con backgroundImage. Agregué este código en el -titleRectForContentRect: de una subclase UIButton, pero el código también se puede colocar en la rutina de dibujo de la supervista UIButton, que en ese caso debe reemplazar todas las referencias a self con la variable UIButton.

 #define TITLE_LABEL_TAG 1234 - (CGRect)titleRectForContentRect:(CGRect)rect { // define the desired title inset margins based on the whole rect and its padding UIEdgeInsets padding = [self titleEdgeInsets]; CGRect titleRect = CGRectMake(rect.origin.x + padding.left, rect.origin.x + padding.top, rect.size.width - (padding.right + padding.left), rect.size.height - (padding.bottom + padding].top)); // save the current title view appearance NSString *title = [self currentTitle]; UIColor *titleColor = [self currentTitleColor]; UIColor *titleShadowColor = [self currentTitleShadowColor]; // we only want to add our custom label once; only 1st pass shall return nil UILabel *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG]; if (!titleLabel) { // no custom label found (1st pass), we will be creating & adding it as subview titleLabel = [[UILabel alloc] initWithFrame:titleRect]; [titleLabel setTag:TITLE_LABEL_TAG]; // make it multi-line [titleLabel setNumberOfLines:0]; [titleLabel setLineBreakMode:UILineBreakModeWordWrap]; // title appearance setup; be at will to modify [titleLabel setBackgroundColor:[UIColor clearColor]]; [titleLabel setFont:[self font]]; [titleLabel setShadowOffset:CGSizeMake(0, 1)]; [titleLabel setTextAlignment:UITextAlignmentCenter]; [self addSubview:titleLabel]; [titleLabel release]; } // finally, put our label in original title view's state [titleLabel setText:title]; [titleLabel setTextColor:titleColor]; [titleLabel setShadowColor:titleShadowColor]; // and return empty rect so that the original title view is hidden return CGRectZero; } 

Me tomé el tiempo y escribí un poco más sobre esto aquí . Allí, también apunto una solución más corta, aunque no encaja en todos los escenarios e involucra algunas pirateo de vistas privadas. También allí, puede descargar una subclase UIButton lista para ser utilizada.

Tienes que agregar este código:

 buttonLabel.titleLabel.numberOfLines = 0; 

En Xcode 9.3 puedes hacerlo usando el guión gráfico siguiente,

enter image description here

Debe configurar el título del botón textoAlineación para centrar

button.titleLabel?.textAlignment = .center

No necesita configurar el texto del título con una nueva línea (\ n) como a continuación,

button.setTitle("Good\nAnswer",for: .normal)

Simplemente establece el título,

button.setTitle("Good Answer",for: .normal)

Aquí está el resultado,

enter image description here

Funciona perfectamente

Agregue para usar esto con el archivo de configuración como Plist, necesita usar CDATA para escribir el título multilínea, así:

  

Si usa el diseño automático en iOS 6, es posible que también deba establecer la propiedad preferredMaxLayoutWidth :

 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; button.titleLabel.textAlignment = NSTextAlignmentCenter; button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width; 

Al establecer lineBreakMode en NSLineBreakByWordWrapping (ya sea en IB o en código), la etiqueta del botón se convierte en una línea múltiple, pero no afecta al marco del botón.

Si el botón tiene un título dynamic, hay un truco: poner UILabel oculto con la misma fuente y atar su altura a la altura del botón con el diseño; cuando se establece el texto en el botón y la etiqueta y el diseño automático hará todo el trabajo.

Nota

La altura de tamaño intrínseco del botón de una línea es más grande que la de la etiqueta, por lo que para evitar que la altura de la etiqueta se reduzca es vertical. La prioridad de abrazamiento debe ser mayor que la resistencia vertical de compresión de contenido del botón.

Si usa el diseño automático.

 button.titleLabel?.adjustsFontSizeToFitWidth = true button.titleLabel?.numberOfLines = 2 
 self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping self.btnError.titleLabel?.textAlignment = .center self.btnError.setTitle("Title", for: .normal) 

Tira tu propia clase de botón. Es, de lejos, la mejor solución a largo plazo. UIButton y otras clases de UIKit son muy restrictivas en cómo puedes personalizarlas.

veloz 4.0

 btn.titleLabel?.lineBreakMode = .byWordWrapping btn.titleLabel?.textAlignment = .center btn.setTitle( "Line1\nLine2", for: .normal) 

Incorporé la respuesta de jessecurry dentro de STAButton, que es parte de mi biblioteca de código abierto STAControls . Actualmente lo uso dentro de una de las aplicaciones que estoy desarrollando y funciona para mis necesidades. Siéntase libre de abrir problemas sobre cómo mejorarlo o enviarme solicitudes de extracción.

Aunque está bien agregar una subvista a un control, no hay garantía de que funcione, porque es posible que el control no espere que esté allí y, por lo tanto, se comporte mal. Si puede salirse con la suya, simplemente agregue la etiqueta como una vista de hermanos del botón y establezca su marco para que se superponga al botón; siempre y cuando esté configurado para aparecer en la parte superior del botón, nada de lo que pueda hacer el botón lo oscurecerá.

En otras palabras:

 [button.superview addSubview:myLabel]; myLabel.center = button.center;