web-dev-qa-db-fra.com

Le texte du titre UIButton n'est pas mis à jour même si je le mets à jour dans le fil principal

J'essaie de changer le titre d'une UIButton que j'ai créée par programme, lorsque l'utilisateur clique dessus. Donc, voici mon code pour créer la UIButton:

myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height)];
[myButton setBackgroundColor:[UIColor blackColor]];
[myButton setAlpha:0.7];
[myButton setTitle:@"Hello" forState:UIControlStateNormal];
[myButton addTarget:self action:@selector(userClicked:) forControlEvents:UIControlEventTouchUpInside];

[parentView addSubview:myButton];

Et, dans ma méthode userClicked:, je fais:

-(void) userClicked:(UIButton*)button
{
    NSLog(@"USER CLICKED!!!");
    if ([NSThread isMainThread])
    {
        NSLog(@"is main thread");
    }

    [button setTitle:@"Bye" forState:UIControlStateHighlighted];
    [button setTitle:@"Bye" forState:UIControlStateNormal];
    [button setTitle:@"Bye" forState:UIControlStateSelected];

    [self someLengthyComputation];
}

La chose étrange est que je peux voir les messages de journal imprimés:

USER CLICKED!!! 
isMainThread

Mais le titre du bouton ne change pas! Qu'est-ce que je fais mal?

EDIT: La définition du titre pour plusieurs états ne fonctionne pas non plus.

EDIT2: Si j'imprime la description du bouton dans la fenêtre de débogage de Xcode, le bon titre

Printing description of button->_titleView:
<UIButtonLabel: 0xa4c9310; frame = (95 216; 130 22); text = 'Bye'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xa44f080>>
37
neutrino

Cela a fonctionné pour moi pour mettre à jour le texte du titre (iOS 7.1, Xcode 5.1):

button.enabled = FALSE;
[button setTitle:@"Test" forState:UIControlStateNormal];
button.enabled = TRUE;
47
Walter Schurter

J'avais le même problème et j'ai remarqué que partout ailleurs je mettais le titre attribué. Ainsi, les mises à jour du titre n'affectaient pas le titre attribué.

Ma solution:

[button setAttributedTitle:@"" forState:UIControlStateNormal];

au lieu de

[button setTitle:@"" forState:UIControlStateNormal];
22
Jeffrey Sun

Pour le moment, le travail le plus court autour de moi est celui-ci:

[button setNeedsLayout];

Après avoir mis à jour le titre.

Cela semble arriver dans iOS 7.1 . Tous mes boutons, qui se comportaient correctement dans les versions précédentes d'iOS (ou peut-être juste compilés avec des SDK précédents), ont soudainement cessé de le faire lorsqu'ils ont été compilés dans Xcode 5.1.1 SDK 7.1.

On dirait que le bug d'Apple.

20
Lukasz

J'ai eu un problème similaire en utilisant des storyboards. En utilisant les réponses ci-dessus, je devais utiliser

[mybutton setTitle:@"SomeText" forState:UIControlStateNormal];
[button setNeedsLayout];
[button layoutIfNeeded];

ET je devais m'assurer que le type de bouton était "Personnalisé" et non "Système" dans l'inspecteur d'attributs. 

10
user3000868

S'il vous plaît voir si cela pourrait vous aider ... quand le bouton est cliqué vérifier la condition si buttonToggled ...

-(IBAction)changeButtonText:(id)sender {
    if (!buttonToggled) {
        [sender setTitle:@"Initial Text" forState:UIControlStateNormal];
        buttonToggled = YES;
    } else {
        [sender setTitle:@"Alternative Text" forState:UIControlStateNormal];
        buttonToggled = NO;
    }
}
7
bachman

Il y a plusieurs problèmes dans votre code:

Vous affectez un rappel au bouton:

@selector(userClicked:)

mais votre code est dans une autre méthode:

-(void)userTapOnTapToRefreshView:(UIButton*)button

Pour résoudre ce problème, vous devez implémenter quelque chose comme ceci:

-(void)userClicked:(id)sender
{
    [(UIButton*)sender setTitle:@"Bye" forState:UIControlStateNormal];
}

De plus, cette partie du code n'a pas de sens pour moi:

[parentView myButton];

Essayez de le changer pour:

[parentView addSubview:myButton];

J'espère que ça va aider :)

6
Flar

Dans iOS 7, le titre d'UIButton n'est pas mis à jour lorsqu'il est désactivé. Cela ressemble à un bug sur iOS 7.

Pour contourner le problème, mettez à jour les titres normal et désactivé. Ça marche!

[button setTitle:title forState:UIControlStateNormal];
[button setTitle:title forState:UIControlStateDisabled];
5
ccoroom

Dans mon cas, j'ai tout essayé mais rien ne fonctionnait. Ensuite, je viens de changer le type de bouton de système à personnalisé à partir de storyboard. BOOM! tout a commencé à se comporter normalement.

4

C’est un peu tard et a quelque chose à voir avec la réponse de Walter Schurter:

J'ai eu un problème similaire où le texte de mon bouton était correctement défini jusqu'à ce que je mette à jour à 7.1. Puis, j'ai constaté que, mon bouton étant désactivé, je devais définir la couleur du titre et le texte du titre pour l'état désactivé afin que le texte s'affiche. Ensuite, tout a fonctionné comme un charme!

4
dragonflyesque

Essaye ça:

[button setTitle:@"Bye" forState:UIControlStateHighlighted];

ou:

[button setTitle:@"Bye" forState:UIControlStateSelected];

Vous pouvez également modifier votre fonction d'annulation:

-(void) userClicked
{
    NSLog(@"USER CLICKED!!!");
    if ([NSThread isMainThread])
    {
        NSLog(@"is main thread");
    }

    [myButton setTitle:@"Bye" forState:UIControlStateNormal];
}
3
Nikos M.

Eh bien, tout est à propos de l'état activé d'un UIButton, Apple a modifié quelque chose en 7.1 qui ne vous permet pas de changer le titre si vous avez l'UIButton sur un état désactivé, c'est tout.

Merci Apple, j'ai perdu 10 min. déboguer une application qui fonctionnait bien. 

Je viens de le découvrir ce matin, j'ai mis à jour le XCode hier en 5.1.1 et iOS en 7.1

2
Kiko Seijo

Cela peut sembler trivial, mais si vous définissez une image de bouton (au lieu d’image d’arrière-plan) qui remplit l’ensemble du cadre du bouton, le titre sera déplacé vers la droite et ainsi rendu invisible. .

2
dobranoc

Changez le type de bouton en "Personnalisé" au lieu de "Système" et tout fonctionnera comme prévu

2
Pulkit Arora

Cela pourrait être le problème d'actualisation de la disposition des boutons ..... Essayez d'utiliser ...

[button setNeedsLayout];
[button layoutIfNeeded];

Cela forcera le bouton à mettre à jour la mise en page.

2
iOSGuest

Il n'y a aucune obligation d'utiliser:

[button setNeedsLayout];
[button layoutIfNeeded];

Au lieu de cela, commencez par définir le type comme DEFAULT surCUSTOM 

Si vous avez appliqué setAttributedTitle, utilisez:

[button setAttributedTitle:[NSAttributedString new] forState:UIControlStateNormal];

Sinon, il n'est pas nécessaire de changer quoi que ce soit. 

Si la couleur du texte n'a pas changé, appliquez la même chose et définissez la couleur du titre avec:

[button setTitleColor:[any_color] forState:UIControlStateNormal];
1
jenish

Pour Swift 3 utilisez simplement les éléments suivants:

button.setTitle("My title", for: .normal)

ou pour un texte attribué

button.setAttributedTitle(<AttributedString>, for: .normal)
1
zero3nna

Selon le guide du développeur Apple, vous ne devez pas définir le texte ou la couleur du titre du bouton directement comme propriété (par exemple, faites pas faites ceci: myButton.titleLabel.text = @ "SomeText" ou myButton.titleLabel.textColor = [UIColor blackColor]). 

Au lieu de cela, vous les définissez en utilisant la fonctionnalité UIButton setter, comme ceci:

    [myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

... ou comme ceci:

    [myButton setTitle:@"SomeText" forState:UIControlStateNormal];.

Voir le guide Apple .

1
Epsilon3

Après avoir essayé de nombreuses solutions, la conclusion consiste à utiliser setAttributedTitle au lieu de setTitle. 

Pour créer la chaîne de titre pour AttributedString:

NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:@" new Test "];

[button setAttributedTitle:attString forState:UIControlStateNormal];

Soit dit en passant, ce problème ne se produit pas occasionnellement en temps normal, mais il se produit soudainement principalement pour les raisons suivantes:

  1. Si vous modifiez l'état activé d'une UIButton et essayez de modifier le titre.

  2. Si vous utilisez une valeur attribuée et souhaitez ensuite la modifier à l'aide de setTitle, la valeur attribuée est supérieure au titre dans ce cas.

  3. Si vous accédez à un autre contrôleur de vue, puis revenez pour mettre à jour le titre du bouton.

1
Amr Angry

Enfin, j'ai compris. Il y avait deux problèmes:

1) button n'était pas dans l'état UIControlStateNormal.

2) J'appelais une méthode effectuant un calcul long juste après la définition du titre, [self someLengthyComputation]

J'ai résolu le problème en:

1) Définition du titre pour tous les états du bouton.

2) Effectuer ce gros calcul dans un autre thread, pas dans le thread principal. 

Mon code de travail est maintenant:

-(void) userClicked:(UIButton*)button
{
    NSLog(@"USER CLICKED!!!");
    if ([NSThread isMainThread])
    {
        NSLog(@"is main thread");
    }

    [button setTitle:@"Bye" forState:UIControlStateHighlighted];
    [button setTitle:@"Bye" forState:UIControlStateNormal];
    [button setTitle:@"Bye" forState:UIControlStateSelected];
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        [self someLengthyComputation];
    });
}

Merci beaucoup à tous ceux qui ont répondu/commenté!

1
neutrino

Aucune de ce qui précède n'a fonctionné pour mon cas (j'avais un bouton au-dessus d'une vue présentée avec UIPopoverController), et j'ai dû supprimerFromSuperview avant setTitle, puis ajouterSubview en arrière - espérons que cela aide quelqu'un avec des problèmes similaires

0
hyouuu

Je doute que 'bouton' passé en tant que paramètre soit myButton. Quoi qu'il en soit, si myButton est un membre var, vous pouvez simplement [myButton setTitle: @ "Bye" pourState: UIControlStateNormal];

0
Hunter

Essayez de déclarer votre bouton en tant que propriété, soit dans l'interface, soit dans la partie implémentation de votre vue/contrôleur.

@property(nonatomic,strong) UIButton* myButton;

puis le créer

self.myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height)];
[_myButton setBackgroundColor:[UIColor blackColor]];
...

Ça devrait marcher. Ne me demandez pas pourquoi vraiment - je pense juste que tout est une question de gestion de mémoire ARC/moderne ..

MODIFIER:

Cela devrait également fonctionner si vous gardez une référence sur le bouton dans votre implémentation.

@implementation myViewController
{
    UIButton* myButton;
}

-(void)createButton
{
    myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height)];
    [myButton setBackgroundColor:[UIColor blackColor]];
    ...
}

...
0
Moose

au lieu de yourButton.titleLabel? .text = "T"

utilise ceci yourButton.setTitle ("TITLE", pour: .normal)

0
Divyanshu Kumar