¿Es posible actualizar el título / texto de UIButton mediante programación?

96

Tengo un UIButton, que cuando se presiona, abre una nueva vista donde el usuario puede cambiar algunas configuraciones. Cuando se descarta la vista, me gustaría actualizar el título / texto UIButtonpara reflejar el nuevo estado. Estoy llamando:

[myButton setTitle: @"myTitle" forState: UIControlStateNormal];
[myButton setTitle: @"myTitle" forState: UIControlStateApplication];
[myButton setTitle: @"myTitle" forState: UIControlStateHighlighted];
[myButton setTitle: @"myTitle" forState: UIControlStateReserved];
[myButton setTitle: @"myTitle" forState: UIControlStateSelected];
[myButton setTitle: @"myTitle" forState: UIControlStateDisabled];

Pero nunca parece cambiar del texto / título original como se especifica en IB.

George Armhold
fuente
2
¿Estás seguro de que se está llamando al código publicado? ¿Hiciste un BREAKPOINT para probar eso? ¿Puede publicar la firma de su delegado?
Pablo Santa Cruz
3
Aparte, creo que puede hacer referencia a varios estados de control a la vez: [myButton setTitle: @ "myTitle" forState :( UIControlStateNormal | UIControlStateApplication | UIControlStateHighlights | ...)]; Tenga en cuenta el uso del operador OR bit a bit en lugar del operador OR lógico (||). En general, cuando se trata de estados como este, puede utilizarlos junto con el | operador. Alguien me corrija si me equivoco gravemente. :)
CIFilter
Ojalá tuvieran uno como UIControlStateAll: D
taber
2
Las combinaciones bit a bit no parecen funcionar para mí en iOS5.
Echilon
El mismo problema aquí. Las combinaciones bit a bit no me funcionan en iOS5. / CC @LucasTizma
znq

Respuestas:

52

¿Tiene el botón especificado como IBOutlet en su clase de controlador de vista y está conectado correctamente como una salida en Interface Builder (ctrl arrastre desde la nueva salida de referencia al propietario del archivo y seleccione su objeto UIButton)? Ese es generalmente el problema que tengo cuando veo estos síntomas.


Editar: si bien no es el caso aquí, algo como esto también puede suceder si establece un título atribuido al botón, luego intenta cambiar el título y no el título atribuido.

Ken Pespisa
fuente
4
Bingo, eso fue todo, gracias. Realmente desearía que Objective-C arrojara una NullPointerException en casos como este, en lugar de fingir silenciosamente que está bien enviar un mensaje a un objeto nulo. Esto me muerde casi a diario ... ¡uf!
George Armhold
20
ObjC no 'finge' que está bien enviar un mensaje a cero, porque está bien enviar mensajes a cero ...
Jasarien
1
El problema aquí no es un indicador nulo. El problema es que IB ha configurado una instancia de UIButton a la que no se hace referencia correctamente en el código (a través de IBOutlet), por lo que nunca se puede manipular mediante programación.
CIFilter
112

Resolví el problema simplemente configurando el parámetro de título para UIControlStateNormal, y funciona automáticamente en los otros estados. El problema parece ser cuando configura otro UIControlState.

[myButton setTitle: @"myTitle" forState: UIControlStateNormal];
Yotes
fuente
15

A partir de Swift 4:

    button.setTitle("Click", for: .normal)
Vlad Spreys
fuente
13

Descubrí otro problema. Puede ser un error introducido en iOS 5, pero pensé en señalarlo a cualquiera que lo encuentre.

Si no establece ningún texto predeterminado para el botón en el XIB, no aparecerá ningún texto si lo establece mediante programación. Y si establece texto en el XIB, cualquier texto que asigne posteriormente al botón mediante programación se truncará al tamaño del texto predeterminado.

Y finalmente, si muestra la vista con su botón y luego invoca otra vista (como una hoja de acción) y luego la descarta, el texto que asignó al botón mediante programación se borrará y el título del botón volverá a lo que haya configurado en el XIB.

Oscar
fuente
1
He notado estos tres comportamientos y ciertamente es molesto.
Pulga
2
Tuve el problema del truncamiento (cambiar el texto a algo más largo mediante programación), así que puse espacios adicionales al final del texto para 'reservar' ese espacio para cuando cambie el texto a una palabra más larga. Eso funcionó para mí.
mattorb
2
Parece que la solución para esto es usar el método [_button setTitle: @ "title" forState: UIControlStateNormal]; en lugar de acceder directamente a la propiedad _button.titleLabel.text. Siga con la llamada al método y probablemente obtendrá lo que desea.
Rymnel
12

Aunque el problema de Caffeine Coma se resolvió, me gustaría ofrecer otra posible causa por la que el título no aparece en un UIButton.

Si configura una imagen para el UIButton usando

- (void)setImage:(UIImage *)image forState:(UIControlState)state

Puede cubrir el título. Descubrí esto por las malas e imagino que algunos de ustedes terminan leyendo esta página por la misma razón.

Utilice este método en su lugar

- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state

para la imagen del botón y el título no se verán afectados.

Probé esto con botones creados mediante programación y botones creados en un .xib

Jesse negro
fuente
7

para rápido:

button.setTitle("Swift", forState: UIControlState.Normal)                   
Dara Tith
fuente
4

¡Resulta que los médicos te dan la respuesta! El UIButton ignorará el cambio de título si ya tiene una Cadena de atributos para usar (parece ser la predeterminada que se obtiene cuando se usa el constructor de interfaces Xcode).

Usé lo siguiente:

[self.loginButton 
     setAttributedTitle:[[NSAttributedString alloc] initWithString:@"Error !!!" attributes:nil] 
     forState:UIControlStateDisabled];
[self.loginButton setEnabled:NO];
CPD
fuente
3

Otra posible causa es esta:

Si intenta establecer el título del botón en el (id)initWithNibName: ...método, la propiedad del botón seguirá siendo nula. Aún no se ha asignado al UIButton.

Debe asegurarse de que está configurando sus botones en un método como (void)viewWillLoado (void)viewWillAppear, pero probablemente no desee configurarlos tan tarde como (void)viewDidAppear.

Ramsey
fuente
2

A veces puede complicarse mucho. ¡La forma más fácil es " actualizar " la vista del botón!

//Do stuff to your button here.  For example:

[mybutton setEnabled:YES];

//Refresh it to new state.

[mybutton setNeedsDisplay];
Mike Rapadas
fuente
1

Seguí teniendo problemas con esto, la única solución era agregar una imagen y etiquetar como subvistas al uibutton. Luego descubrí que el problema principal era que estaba usando un UIButton con título: Atribuido. Cuando lo cambié a Plain, ¡simplemente estableciendo el titleLabel.text funcionó!

marca
fuente
1

@funroll tiene toda la razón. Aquí puede ver lo que necesita Asegúrese de que la función se ejecute solo en el hilo principal . Si no desea tratar con subprocesos, puede hacerlo así, por ejemplo: crear NSUserDefaults y en ViewDidLoad se presionó el botón de verificación en otra Vista o no (en otra Vista establecida en NSUserDefaults se necesitaba información) y dependiendo de las condiciones, establezca el título necesario para su UIButton, entonces [yourButton setTitle: @ "Title" forState: UIControlStateNormal];

Daleijn
fuente
Esto fue muy útil para mí ... resulta que si llamas a setTitle y setNeedsDisplay desde un hilo en segundo plano, la Vista se actualizará mucho más tarde.
user1111828
0

Asegúrate de estar en el hilo principal.

De lo contrario, se guardará el texto del botón. Estará allí cuando inspeccione el objeto en el depurador. Pero en realidad no actualizará la vista.

funroll
fuente