2013-07-31 18 views
10

Ho un UIView che contiene un UIButton. UIButton ha 2 titoli impostati per gli stati UIControlStateNormal ("Follow") e UIControlStateSelected ("Following"). Sto usando il layout automatico su UIButton e ha un vincolo per essere una certa distanza dalla parte superiore del superview e un altro per essere una certa distanza dal lato sinistro del superview. Ho anche usato "Dimensioni per adattarsi ai contenuti" su di esso.La dimensione intrinseca non si aggiorna quando si cambia lo stato di UIButton

Quando si imposta il pulsante nello stato selezionato dal codice, il titolo cambia correttamente ma la larghezza intrinseca di UIButton non cambia in modo che quando si passa da "Segui" a "Seguendo" il testo viene ellittizzato.

self.selected = self.following; 

enter image description hereenter image description here

Quando mi avvicino il problema in modo diverso e semplicemente cambiare il testo per UIControlStateNormal quando qualcuno preme il pulsante, il pulsante si trasforma dimensioni in modo corretto.

NSString *title = (self.following) ? @"Following" : @"Follow" 
[self setTitle:title forState:UIControlStateNormal]; 

enter image description hereenter image description here

È questo un bug in UIKit? Mi aspetto che il pulsante cambi la sua dimensione intrinseca per riflettere correttamente la nuova dimensione del testo quando il suo stato cambia, specialmente perché ci sono altre cose che vorrei cambiare oltre al testo per gli stati dei 2 pulsanti.

risposta

21

Come Davide Caunt ha sottolineato in un commento, chiamando invalidateIntrinsicContentSize causerà layout automatico per ridimensionare il pulsante per adattarsi sia nuovi contenuti .

self.selected = self.following; 
[self invalidateIntrinsicContentSize]; 

PS. David, se vuoi postare il tuo commesso come risposta, rimuoverò il mio.

+1

Qualcuno ha provato questo di recente (iOS 8.2+)? L'unica soluzione diretta che funziona per me è setTitle di @ abdullah: forState. Ho anche provato a seguire quella linea con layoutIfNeeded. –

+0

per essere completo e compatibile con qualsiasi sistema di layout che ho dovuto seguire con chiamare setNeedsLayout e chiamarlo su ogni superview di superview fino a quando non c'è più ... sembra essere l'unico modo in cui il cambiamento si applica a tutto ciò che la dimensione può impatto. (se inserito in sottoview ecc.) – Ben

1

Nello storyboard seleziona il tuo UIButton e in alto seleziona editor-> dimensione per adattarlo alle dimensioni del contenuto.

EDIT: Prova questo:

[self.myButton setTitle:@"Following" forState:UIControlStateSelected]; 
[self.myButton sizeToFit]; 
+0

Ho provato questo, è menzionato nella domanda. – jvergeldedios

+0

@jvedi Assicurati che UIButton sia selezionato quando lo fai. –

+0

Era, ancora nessun cambiamento. – jvergeldedios

0

se si tratti di un bug, o semplicemente il modo in cui è, non lo so, ma sembra che si dovrà lavorare intorno ad esso - - Non penso che tu stia facendo qualcosa di sbagliato. Se si vuole passare da selezionato e non dopo ogni tocco, si potrebbe fare qualcosa di simile:

- (IBAction)buttonClick:(UIButton *)sender { 
    sender.selected = !sender.selected; 
    if (sender.selected) { 
     [self.button setTitle:@"Following" forState:UIControlStateNormal]; 
     //Do whatever else you want to do here for the selected state 
    }else{ 
     [self.button setTitle:@"Follow" forState:UIControlStateNormal]; 
    } 
} 
+0

Alla fine ho optato per qualcosa di simile, ma mi sembra ancora strano che il passaggio allo stato non funzioni solo così. Oh bene. – jvergeldedios

+0

@jvedi, sono d'accordo. Sembra strano che la dimensione intrinseca non funzioni per UIControlStateSelected. Sembra qualcosa che Apple ha appena dimenticato di implementare. – rdelmar

+6

Devi solo chiamare 'invalidateIntrinsicContentSize' e dovrebbe funzionare. 'setTitle: forState' probabilmente chiama internamente questo metodo. –

1

Per me impostare il contentEdgeInsets mi ha fornito l'unica soluzione affidabile.

Uso pulsanti personalizzati, con immagini di sfondo. Quindi, le fette entrano in scena. Si scopre che il modo in cui affetti le immagini può anche influire sulla dimensione del contenuto intrinseco! Provalo! Quindi, dovevo assicurarmi che stavo tagliando identicamente tra le immagini per diversi stati. Sto anche usando le stringhe attribuite. Le soluzioni pubblicate qui non hanno funzionato per il mio caso.

Quello che ho trovato dopo un giorno (!) Di sperimentazione è che l'impostazione di valori sufficienti di contentEdgeInsets sul pulsante lo rende corretto quando i titoli vengono modificati utilizzando l'autolayout. Non è necessario invalidare le dimensioni del contenuto intrinseco o chiamare qualsiasi codice di layout se si esegue questa operazione.

È possibile impostare contentEdgeInsets nel codice o in IB.

self.button.contentEdgeInsets = UIEdgeInsetsMake(10.0, 16.0, 10.0, 16.0); 

Penso che il codice Swift sia identico tranne per l'attributo var.

Apple dice questo nei documenti: "Il pulsante utilizza questa proprietà per determinare intrinsicContentSize e sizeThatFits :.".

enter image description here

Problemi correlati