[objective-c] Come fermare l'animazione UIButton indesiderata sul cambio del titolo?



9 Answers

Utilizza il metodo performWithoutAnimation: e quindi performWithoutAnimation: il layout a verificarsi immediatamente anziché in seguito.

[UIView performWithoutAnimation:^{
  [self.myButton setTitle:text forState:UIControlStateNormal];
  [self.myButton layoutIfNeeded];
}];
Question

In iOS 7 i miei titoli UIButton si animano dentro e fuori al momento sbagliato - tardi. Questo problema non appare su iOS 6. Sto solo usando:

[self setTitle:text forState:UIControlStateNormal];

Preferirei che ciò accadesse all'istante e senza una cornice vuota. Questo battito di ciglia è particolarmente distraente e distoglie l'attenzione dalle altre animazioni.




Ho avuto il brutto problema di animazione quando cambiavo i titoli dei pulsanti nei controller di visualizzazione all'interno di UITabBarController. I titoli originariamente impostati nello storyboard si presentavano per un breve periodo prima di dissolversi nei loro nuovi valori.

Volevo scorrere tutte le sottoview e usare i titoli dei pulsanti come chiavi per ottenere i loro valori localizzati con NSLocalizedString, come;

for(UIView *v in view.subviews) {

    if ([v isKindOfClass:[UIButton class]]) {
        UIButton *btn = (UIButton*)v;
        NSString *newTitle = NSLocalizedString(btn.titleLabel.text, nil);
        [btn setTitle:newTitle];
    }

}

Ho scoperto che l'attivazione dell'animazione è in realtà la chiamata a btn.titleLabel.text. Quindi, per fare ancora uso degli storyboard e avere i componenti dinamicamente localizzati come questo, mi assicuro di impostare l'ID di ripristino di ogni pulsante (in Identity Inspector) allo stesso titolo e usarlo come chiave al posto del titolo;

for(UIView *v in view.subviews) {

    if ([v isKindOfClass:[UIButton class]]) {
        UIButton *btn = (UIButton*)v;
        NSString *newTitle = NSLocalizedString(btn.restorationIdentifier, nil);
        [btn setTitle:newTitle];
    }

}

Non ideale, ma funziona ..




Imposta il tipo UIButton come personalizzato. Questo dovrebbe rimuovere le animazioni in entrata e in uscita.




Ho capito che funziona con una combinazione di risposte:

[[[button titleLabel] layer] removeAllAnimations];

    [UIView performWithoutAnimation:^{

        [button setTitle:@"Title" forState:UIControlStateNormal];

    }];



Cambia il tipo di pulsante in Generatore di interfaccia modulo personalizzato.

Questo ha funzionato per me.




Ho fatto un'estensione Swift per fare questo:

extension UIButton {
    func setTitleWithoutAnimation(title: String?) {
        UIView.setAnimationsEnabled(false)

        setTitle(title, forState: .Normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

Funziona per me su iOS 8 e 9, con UIButtonTypeSystem .

(Il codice è per Swift 2, Swift 3 e Objective-C dovrebbe essere simile)




La combinazione di grandi risposte sopra comporta la seguente soluzione alternativa per UIButtonTypeSystem :

if (_button.enabled)
{
    [UIView setAnimationsEnabled:NO];
    [_button setTitle:@"title" forState:UIControlStateNormal];
    [UIView setAnimationsEnabled:YES];
}
else // disabled
{
    [UIView setAnimationsEnabled:NO];
    _button.enabled = YES;
    [_button setTitle:@"title" forState:UIControlStateNormal];
    _button.enabled = NO;
    [UIView setAnimationsEnabled:YES];
}



In Swift puoi usare:

UIView.performWithoutAnimation {
    self.someButtonButton.setTitle(newTitle, forState: .normal)
    self.someButtonButton.layoutIfNeeded()
}



Di solito basta semplicemente impostare il tipo di pulsante su Personalizza per me, ma per altri motivi ho avuto bisogno di sottoclasse UIButton e di riportare il tipo di pulsante al valore predefinito (Sistema), quindi il lampeggio è riapparso.

Impostando UIView.setAnimationsEnabled(false) prima di cambiare il titolo e poi di nuovo su true dopo questo non ho evitato di lampeggiare per me, non importa se ho chiamato self.layoutIfNeeded() o meno.

Questo, e solo questo nel seguente ordine esatto, ha funzionato per me con iOS 9 e 10 beta:

1) Crea una sottoclasse per UIButton (non dimenticare di impostare anche la classe personalizzata per il pulsante nello Storyboard).

2) Override setTitle:forState: come segue:

override func setTitle(title: String?, forState state: UIControlState) {

    UIView.performWithoutAnimation({

        super.setTitle(title, forState: state)

        self.layoutIfNeeded()
    })
}

In Interface Builder, puoi lasciare il tipo di pulsante su Sistema, non è necessario cambiarlo in Tipo personalizzato per far funzionare questo approccio.

Spero che questo aiuti qualcun altro, ho faticato tanto a lungo con i fastidiosi pulsanti intermittenti che spero di evitare ad altri;)




Puoi semplicemente creare un pulsante personalizzato e smetterà di animare mentre cambi il titolo.

        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setTitle:@"the title" forState:UIControlStateNormal];

puoi anche farlo nella casella di controllo Storyboard: seleziona il pulsante nello storyboard -> seleziona l'ispettore attributi (quarto da sinistra) -> nel menu a discesa "Tipo", seleziona "Personalizzato" invece di "Sistema" che era probabilmente selezionato .

In bocca al lupo!






Related