UIButton con dos líneas de texto en el título (numberOfLines = 2)

86

Estoy tratando de hacer un UIButtonque tenga dos líneas de texto en su titleLabel. Este es el código que estoy usando:

    UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleButton.titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    [titleButton setTitle:@"This text is very long and should get truncated at the end of the second line" forState:UIControlStateNormal];
    titleButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    titleButton.titleLabel.numberOfLines = 2;
    [self addSubview:titleButton];

Cuando intento esto, el texto solo aparece en una línea. Parece que la única forma de lograr más de una línea de texto UIButton.titleLabeles establecer numberOfLines=0y usarUILineBreakModeWordWrap . Pero esto no garantiza que el texto tenga exactamente dos líneas.

UILabelSin embargo, usar un plano funciona:

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
    titleLabel.numberOfLines = 2;
    titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    [self addSubview:titleLabel];

¿Alguien sabe cómo hacer el UIButtontrabajo con dos líneas? ¿Es la única solución crear un elemento separado UILabelpara contener el texto y agregarlo como una subvista del botón?

comercializador
fuente
1
Has visto esto ? - stackoverflow.com/questions/604632/…
Viraj
Viraj, sí, si configura numberOfLines=0y usa UILineBreakModeWordWrap, puede obtener varias líneas. El problema con eso es que podría dar más de dos líneas si el texto es demasiado largo. Quiero exactamente dos solitarios con puntos suspensivos al final de la segunda línea (si el texto es demasiado largo).
comercializador
Oh, entonces supongo que agregar una subvista puede ser la única forma de hacerlo.
Viraj

Respuestas:

87

Respuesta actualizada para versiones de iOS más recientes

Dado que esta es la respuesta aceptada, agregue la respuesta de @ Sean aquí:

Establezca estas propiedades en el titleLabel de su botón.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2; // if you want unlimited number of lines put 0

Swift 3 y 4:

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.numberOfLines = 2 // if you want unlimited number of lines put 0

Respuesta original para una versión anterior de iOS

Si desea 2 líneas de texto encima UIButton, debe agregar una UIlabelencima que haga precisamente eso.

UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
titleLabel.numberOfLines = 2;
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
[myButton addSubview:titleLabel]; //add label to button instead.

Actualizado para la solución de creación de interfaces

Se agregó la respuesta de @Borut Tomazin para una respuesta más completa. Se actualizó esta parte nuevamente desde que se mejoró la respuesta de @Borut Tomazin.

Puede hacer esto mucho más fácilmente, sin necesidad de código. En Interface Builder, establezca Line BreakUIButton en Word Wrap. Entonces puede insertar varias líneas de título. Simplemente presione las Option + Returnteclas para hacer una nueva línea. También deberá agregar esto al atributo de tiempo de ejecución definido por el usuario en Interface Builder:

titleLabel.textAlignment Number [1]
Totumus Maximus
fuente
5
UILineBreakModeestán obsoletos, utilícelos NSLineBreakModeen su lugar
guillaume
2
Esto es innecesario a partir de las versiones recientes de iOS. Vea la respuesta de @ sean.
cbowns
146

No es necesario agregar un UILabel al UIButton. Eso es solo objetos extra y trabajo.

Establezca estas propiedades en el titleLabel de su botón.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2;//if you want unlimited number of lines put 0

Rápido:

button.titleLabel!.lineBreakMode = NSLineBreakMode.ByWordWrapping
button.titleLabel!.numberOfLines = 2//if you want unlimited number of lines put 0
Sean
fuente
6
Este es el 2013 y, a día de hoy, esta es la solución de vanguardia.
Klaas
@Blip, lamentablemente no puedes y necesitas hacerlo en código. Podría valer la pena presentar un informe de error a Apple solicitando esta funcionalidad.
bpapa
@bpapa Sí, estoy de acuerdo, los guiones gráficos deberían ser más flexibles.
Blip
6
Esto funciona para mí, sin embargo, rompe el comportamiento predeterminado del botón intrinsicContentSize, que aún devuelve una altura que corresponde a una sola línea de texto. Lo arreglé anulando el botón intrinsicContentSizedonde configuré la altura [self.titleLabel sizeThatFits(CGSizeMake(self.titleLabel.frame.size.width, CGFLOAT_MAX)].height.
Elise
@WillVonUllrich porque solo puede cambiar la respuesta aceptada cuando se edita. Agregué estas respuestas a la aceptada para que ayude a las personas que no buscan más allá de la respuesta aceptada.
Totumus Maximus
88

Puede hacer esto mucho más fácilmente, sin necesidad de código. En Interface Builder, establezca Line BreakUIButton en Word Wrap. Entonces puede insertar varias líneas de título. Simplemente presione las Option + Returnteclas para hacer una nueva línea. También deberá agregar esto al atributo de tiempo de ejecución definido por el usuario en Interface Builder:

titleLabel.textAlignment Number [1]

Es así de simple. Espero eso ayude...

Borut Tomazin
fuente
1
Esta solución es mejor (menos objetos, código) que la actualmente aceptada, para casos simples.
Jonathan Zhan
1
Establece exactamente las mismas propiedades que lo haría mediante programación, por lo que su argumento "menos objetos" no es válido. El código es quizás menor. Pero es más legible. Elija su opción;)
Totumus Maximus
Oh, creo que no estaba claro. Gracias por intentar aclarar. No estaba tan preocupado por el hecho de que se hace en IB vs Code. Más que ver con el hecho de que no necesita agregar una etiqueta adicional con la solución de Borut, y que también logra lo mismo. Pero sí, ambos funcionan muy bien. :)
Jonathan Zhan
es realmente abrumador tener que ir al código para una tarea tan básica.
Can Poyrazoğlu
3
Puede lograr el mismo objetivo 100% sin código agregando el titleLabel.textAlignment Atributo de tiempo de ejecución definido por el usuario en Interface Builder y configurándolo en Número = 1 (valor de NSTextAlignmentCenter).
0xced el
21
 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;

button.titleLabel.textAlignment = NSTextAlignmentCenter;

[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];
Suraj K Thomas
fuente
¡Perfecto! No tienes que dividir el NSStringinterior setTitle. ¡WordWrapping lo está haciendo por usted!
Alex Cio
Para mí, tuve que dividir la cadena dentro del título del conjunto. Sin eso no funcionó
user1960169
9

Para evitar por completo la necesidad de editar el código y, por lo tanto, la necesidad de subclasificar su vista, en Xcode5 y superior puede seguir la sugerencia de Borut Tomazin:

En Interface Builder (o guión gráfico), establezca Salto de línea en Ajuste de palabra. Entonces puede insertar varias líneas de título. Simplemente presione las teclas Option+ Returnpara hacer una nueva línea.

y luego, en los atributos de tiempo de ejecución definidos por el usuario , puede agregar

Ruta de la clave: titleLabel.textAlignment
Tipo: Number
Valor:1

Nota: esto puede no ser completamente "a prueba de futuro" ya que estamos traduciendo la UITextAlignmentCenterconstante a su valor numérico (y esa constante puede cambiar a medida que se lanzan nuevas versiones de iOS), pero parece seguro en un futuro cercano.

furinos
fuente
0

Puede modificar el valor necesario directamente desde Storyboard. Seleccione el botón, vaya al inspector de identidad y agregue el siguiente par clave-valor en la sección "Atributos de tiempo de ejecución definidos por el usuario":

ingrese la descripción de la imagen aquí

Arik Segal
fuente