est-il possible de mettre à jour le titre / texte UIButton par programmation?


96

J'ai un UIButton, qui, lorsqu'il est pressé, fait apparaître une nouvelle vue où l'utilisateur peut modifier certains paramètres. Lorsque la vue est rejetée, j'aimerais mettre à jour le titre / texte du UIButtonpour refléter le nouvel état. J'appelle:

[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];

Mais cela ne semble jamais changer par rapport au texte / titre original tel que spécifié dans IB.


2
Êtes-vous sûr que le code affiché est appelé? Avez-vous placé un BREAKPOINT pour le prouver? Pouvez-vous publier la signature de votre délégué?
Pablo Santa Cruz

3
En passant, je crois que vous pouvez référencer plusieurs états de contrôle à la fois: [myButton setTitle: @ "myTitle" forState :( UIControlStateNormal | UIControlStateApplication | UIControlStateHighlighted | ...)]; Notez l'utilisation de l'opérateur OR au niveau du bit par opposition à l'opérateur logique OR (||). En général, lorsque vous traitez avec des états comme celui-ci, vous pouvez les OU avec le | opérateur. Quelqu'un me corrige si je me trompe grossièrement. :)
CIFilter

J'aurais aimé qu'ils en aient un comme UIControlStateAll: D
taber

2
Les combinaisons au niveau du bit ne semblent pas fonctionner pour moi dans iOS5.
Echilon

Même problème ici. Les combinaisons au niveau du bit ne fonctionnent pas pour moi sur iOS5. / CC @LucasTizma
znq

Réponses:


52

Le bouton est-il spécifié en tant qu'IBOutlet dans votre classe de contrôleur de vue et est-il correctement connecté en tant que sortie dans Interface Builder (faites glisser le curseur de la nouvelle sortie de référencement vers le propriétaire du fichier et sélectionnez votre objet UIButton)? C'est généralement le problème que j'ai lorsque je vois ces symptômes.


Modifier: Bien que ce ne soit pas le cas ici, quelque chose comme cela peut également se produire si vous définissez un titre attribué au bouton, puis que vous essayez de changer le titre et non le titre attribué.


4
Bingo, c'était tout, merci. Je souhaite vraiment qu'Objective-C lève simplement une NullPointerException dans des cas comme celui-ci, au lieu de prétendre silencieusement qu'il est OK d'envoyer un message à un objet nul. Cela me mord presque tous les jours ... ugh!
George Armhold

20
ObjC ne `` prétend '' pas son OK pour envoyer un message à nil, car il est OK pour envoyer des messages à nil ...
Jasarien

1
Le problème ici n'est pas un pointeur nul. Le problème est qu'IB a configuré une instance UIButton qui n'est pas référencée correctement dans le code (via IBOutlet), de sorte qu'elle ne peut jamais être manipulée par programme.
CIFilter

112

J'ai résolu le problème en définissant simplement le paramètre de titre pour UIControlStateNormal, et cela fonctionne automatiquement sur les autres états. Le problème semble être lorsque vous définissez un autre UIControlState.

[myButton setTitle: @"myTitle" forState: UIControlStateNormal];


13

J'ai découvert un autre problème. C'est peut-être un bogue introduit dans iOS 5, mais j'ai pensé le signaler à quiconque le rencontrait.

Si vous ne définissez aucun texte par défaut pour le bouton dans le XIB, aucun texte n'apparaîtra jamais si vous le définissez par programme. Et si vous définissez du texte dans le XIB, tout texte que vous attribuez par la suite au bouton par programme sera tronqué à la taille du texte par défaut.

Et enfin, si vous affichez la vue avec votre bouton, puis invoquez une autre vue (comme une feuille d'action), puis la rejetez, le texte que vous avez attribué au bouton par programme sera effacé et la légende du bouton reviendra à ce que vous avez défini dans le XIB.


1
J'ai remarqué ces trois comportements et c'est certainement ennuyeux.
Flea

2
J'ai eu le problème de troncature (changer le texte en quelque chose de plus long par programmation), donc j'ai mis des espaces supplémentaires à la fin du texte pour `` réserver '' cet espace lorsque je change le texte en un mot plus long. Cela a fonctionné pour moi.
mattorb

2
Il semble que le correctif pour cela consiste à utiliser la méthode [_button setTitle: @ "title" forState: UIControlStateNormal]; au lieu d'accéder directement à la propriété _button.titleLabel.text. Restez fidèle à l'appel de méthode et vous obtiendrez probablement ce que vous voulez.
Rymnel

12

Même si le problème de Caffeine Coma a été résolu, je voudrais offrir une autre cause potentielle pour que le titre n'apparaisse pas sur un UIButton.

Si vous définissez une image pour l'UIButton en utilisant

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

Il peut couvrir le titre. J'ai découvert cela à la dure et j'imagine que certains d'entre vous finissent par lire cette page pour la même raison.

Utilisez plutôt cette méthode

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

pour l'image du bouton et le titre ne seront pas affectés.

J'ai testé cela avec des boutons créés par programme et des boutons créés dans un fichier .xib


7

pour swift:

button.setTitle("Swift", forState: UIControlState.Normal)                   

4

Il s'avère que les documents vous donnent la réponse! UIButton ignorera le changement de titre s'il a déjà une chaîne attribuée à utiliser (avec semble être la valeur par défaut que vous obtenez lorsque vous utilisez le générateur d'interface Xcode).

J'ai utilisé ce qui suit:

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

3

Une autre cause possible est la suivante:

Si vous essayez de définir le titre du bouton dans la (id)initWithNibName: ...méthode, la propriété de votre bouton sera toujours nulle. Il n'a pas encore été attribué à l'UIButton.

Vous devez être sûr de définir vos boutons dans une méthode telle que (void)viewWillLoadou (void)viewWillAppear, mais vous ne voulez probablement pas les définir aussi tard que (void)viewDidAppear.


2

Parfois, cela peut devenir vraiment compliqué. Le moyen le plus simple est de " rafraîchir " la vue des boutons!

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

[mybutton setEnabled:YES];

//Refresh it to new state.

[mybutton setNeedsDisplay];

1

J'ai continué à avoir des problèmes avec cela, la seule solution était d'ajouter une image et une étiquette en tant que sous-vues à uibutton. Puis j'ai découvert que le problème principal était que j'utilisais un UIButton avec le titre: Attribué. Quand je l'ai changé en Plain, le simple réglage du titleLabel.text a fait l'affaire!


1

@funroll a tout à fait raison. Ici vous pouvez voir ce dont vous aurez besoin Assurez-vous que la fonction ne s'exécute que sur le thread principal . Si vous ne voulez pas traiter les threads, vous pouvez faire comme ceci par exemple: créer NSUserDefaults et dans ViewDidLoad la condition de contrôle a été pressé sur le bouton dans une autre vue ou non (dans une autre vue définie dans NSUserDefaults, les informations nécessaires) et en fonction des conditions définies, le titre nécessaire pour votre UIButton, donc [yourButton setTitle: @ "Title" forState: UIControlStateNormal];


Cela m'a été très utile ... il s'avère que si vous appelez setTitle et setNeedsDisplay à partir d'un thread d'arrière-plan, la vue sera mise à jour beaucoup plus tard.
user1111828

0

Assurez-vous que vous êtes sur le fil principal.

Sinon, il enregistrera toujours le texte du bouton. Il sera là lorsque vous inspecterez l'objet dans le débogueur. Mais cela ne mettra pas à jour la vue.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.