web-dev-qa-db-de.com

Der UIButton-Titeltext wird nicht aktualisiert, auch wenn ich ihn im Haupt-Thread aktualisiere

Ich versuche, den Titel einer UIButton zu ändern, die ich programmgesteuert erstellt habe, wenn der Benutzer darauf klickt. Dies ist mein Code zum Erstellen der 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];

Und in meiner userClicked:-Methode mache ich:

-(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];
}

Das Seltsame ist, dass ich die Protokollnachrichten ausdrucken kann:

USER CLICKED!!! 
isMainThread

Der Titel der Schaltfläche ändert sich jedoch nicht! Was mache ich falsch?

BEARBEITEN: Das Einstellen des Titels für mehrere Status funktioniert ebenfalls nicht.

EDIT2: Wenn ich die Beschreibung der Schaltfläche im Debugger-Fenster von Xcode drucke, wird der richtige Titel angezeigt!

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

Dies funktionierte für mich, um den Titeltext zu aktualisieren (iOS 7.1, Xcode 5.1):

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

Ich hatte das gleiche Problem und bemerkte, dass ich überall den attributedTitle gesetzt habe. Daher hatten alle Aktualisierungen des Titels keinen Einfluss auf den zugewiesenen Titel.

Meine Lösung:

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

anstatt

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

Momentan nennt mich die kürzeste Arbeit, mit der ich gekommen bin:

[button setNeedsLayout];

Nachdem Sie den Titel aktualisiert haben.

Dies scheint in iOS 7.1 zu passieren. Alle meine Schaltflächen, die sich in früheren iOS-Versionen korrekt verhalten haben (oder vielleicht nur mit vorherigen SDKs kompiliert wurden), haben dies plötzlich beendet, wenn sie in Xcode 5.1.1 SDK 7.1 kompiliert wurden.

Sieht aus wie Apples Fehler.

20
Lukasz

Ich hatte ein ähnliches Problem bei der Verwendung von Storyboards. Mit den Antworten oben musste ich verwenden

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

UND ich musste sicherstellen, dass der Button-Typ im Attribut-Inspector "Benutzerdefiniert" und nicht "System" war. 

10
user3000868

Bitte prüfen Sie, ob dies Ihnen helfen kann ... Wenn Sie auf die Schaltfläche klicken, überprüfen Sie die Bedingung, ob die Schaltfläche "Umgeschaltet" ist

-(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

In Ihrem Code gibt es mehrere Probleme:

Sie weisen der Schaltfläche einen Rückruf zu:

@selector(userClicked:)

aber Ihr Code ist in einer anderen Methode:

-(void)userTapOnTapToRefreshView:(UIButton*)button

Um dies zu beheben, müssen Sie Folgendes implementieren:

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

Auch dieser Teil des Codes macht für mich keinen Sinn:

[parentView myButton];

Versuchen Sie es zu ändern in:

[parentView addSubview:myButton];

Hoffe es wird helfen :)

6
Flar

In iOS 7 wird der Titel von UIButton nicht aktualisiert, wenn er deaktiviert ist. Es scheint ein Fehler unter iOS 7 zu sein.

Aktualisieren Sie als Problemumgehung sowohl den normalen als auch den deaktivierten Titel. Es klappt!

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

In meinem Fall habe ich alles versucht, aber nichts hat funktioniert. Dann habe ich den Knopf-Typ vom System in den benutzerdefinierten Bereich des Storyboards geändert. BOOM! alles begann sich normal zu verhalten.

Das ist ein bisschen spät und hat etwas mit Walter Schurter zu tun:

Ich hatte ein ähnliches Problem, bei dem mein Schaltflächentext korrekt festgelegt wurde, bis ich auf 7.1 aktualisiert wurde. Da ich meine Schaltfläche deaktiviert hatte, musste ich die Titelfarbe und den Titeltext für den deaktivierten Status festlegen, damit der Text angezeigt wird. Dann funktionierte alles wie ein Zauber!

4
dragonflyesque

Versuche dies:

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

oder:

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

Sie können auch Ihre Void-Funktion ändern:

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

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

Nun, es geht um den aktivierten Status eines UIButton, Apple hat in 7.1 etwas geändert, was es Ihnen nicht erlaubt, den Titel zu ändern, wenn Sie den UIButton auf einem deaktivierten Status haben, das ist alles.

Danke Apple, ich habe 10 Minuten verloren. Debuggen einer App, die einwandfrei funktionierte. 

Habe gerade heute morgen rausgefunden, gestern XCode auf 5.1.1 und iOS auf 7.1 aktualisiert

2
Kiko Seijo

Dies kann trivial sein, aber wenn Sie ein Schaltflächenbild (anstelle eines Hintergrundbildes) einstellen, das den gesamten Schaltflächenrahmen ausfüllt, wird der Titel nach rechts verschoben und somit unsichtbar. Wenn dies der Fall ist, ändern Sie das Schaltflächenbild in ein Hintergrundbild .

2
dobranoc

Ändern Sie den Schaltflächentyp in "Benutzerdefiniert" anstelle von "System" und es wird wie erwartet funktionieren :)

2
Pulkit Arora

Es könnte sich um ein Problem mit der Tastenlayoutaktualisierung handeln. Versuchen Sie es mit ...

[button setNeedsLayout];
[button layoutIfNeeded];

Die Taste wird gezwungen, das Layout zu aktualisieren.

2
iOSGuest

Es besteht keine Anforderung zur Verwendung von:

[button setNeedsLayout];
[button layoutIfNeeded];

Setzen Sie den Typ stattdessen als DEFAULT aufCUSTOM 

Wenn Sie setAttributedTitle angewendet haben, verwenden Sie:

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

Ansonsten müssen Sie nichts ändern. 

Wenn sich die Farbe des Textes nicht geändert hat, wenden Sie dasselbe an und setzen Sie die Titelfarbe mit:

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

Für Swift 3 verwenden Sie einfach Folgendes:

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

oder für einen zugeschriebenen Text

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

Laut Apple-Entwicklerhandbuch sollten Sie weder den Beschriftungstext als auch die Farbe der Schaltfläche direkt als Eigenschaft festlegen. Führen Sie beispielsweise not Folgendes aus: myButton.titleLabel.text = @ "SomeText" oder myButton.titleLabel.textColor = [UIColor blackColor]). 

Sie legen sie stattdessen mit der UIButton-Setterfunktion wie folgt fest:

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

... oder so:

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

Siehe die Apple-Anleitung .

1
Epsilon3

Schlussfolgerung nach dem Ausprobieren vieler Lösungen ist die Verwendung von setAttributedTitle anstelle von setTitle. 

So erstellen Sie die Titelzeichenfolge für AttributedString:

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

[button setAttributedTitle:attString forState:UIControlStateNormal];

Übrigens tritt dieses Problem im Normalfall nicht gelegentlich auf, aber es tritt plötzlich hauptsächlich aus folgenden Gründen auf:

  1. Wenn Sie den aktivierten Status einer UIButton ändern und versuchen, den Titel zu ändern.

  2. Wenn Sie einen Attributwert verwenden und ihn dann mit setTitle ändern möchten, ist der Attributwert in diesem Fall dem Titel überlegen.

  3. Wenn Sie zu einem anderen Ansichtscontroller navigieren und dann zurückkehren, um den Schaltflächentitel zu aktualisieren.

1
Amr Angry

Zum Schluss habe ich es herausgefunden. Es gab zwei Probleme:

1) button war nicht im Zustand UIControlStateNormal.

2) Ich habe eine Methode aufgerufen, die kurz nach dem Setzen des Titels [self someLengthyComputation] eine lange Berechnung durchführt. 

Ich habe das Problem gelöst durch:

1) Einstellen des Titels für alle Status der Schaltfläche.

2) Ausführen dieser großen Berechnung in einem anderen Thread, nicht im Haupt-Thread. 

Mein Arbeitscode ist jetzt:

-(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];
    });
}

Vielen Dank an alle, die geantwortet/kommentiert haben!

1
neutrino

Keines der oben genannten Probleme funktionierte für meinen Fall (ich hatte einen Button oben auf einer Ansicht, die mit UIPopoverController dargestellt wurde), und ich mussteFromSuperview vor setTitle entfernen und dannSubview wieder hinzufügen. Ich hoffe, das hilft jemandem, der ähnliche Probleme hat

0
hyouuu

Ich bezweifle, dass der als Parameter übergebene 'button' meinButton ist. Jedenfalls, wenn myButton ein Member-Var ist, können Sie [myButton setTitle: @ "Bye" forState: UIControlStateNormal];

0
Hunter

Versuchen Sie, den Button als Eigenschaft zu deklarieren, entweder in der Schnittstelle oder im Implementierungsteil Ihres View/View-Controllers

@property(nonatomic,strong) UIButton* myButton;

dann erstellen Sie es

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

Es sollte funktionieren. Fragen Sie mich nicht warum? Ich denke nur, es geht um ARC/Modernes Speichermanagement.

BEARBEITEN:

Es sollte auch funktionieren, wenn Sie in Ihrer Implementierung einen Verweis auf der Schaltfläche beibehalten.

@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

statt yourButton.titleLabel? .text = "T"

Verwenden Sie diesen yourButton.setTitle ("TITLE" für: .normal)

0
Divyanshu Kumar