2014-10-29 9 views
14

Sto lavorando su una tastiera per iOS 8 utilizzando l'Autolayout per posizionare i pulsanti sulla vista.
Quando cambio il layout utilizzando i vincoli, tutto appare in modo corretto sullo schermo, ma quando voglio conoscere le dimensioni del fotogramma della vista, non ottengo le dimensioni corrette.Autolayout iOS - Dimensione frame non impostata in viewDidLayoutSubviews

Ad esempio: premo un tasto, il layout della tastiera cambia e impagina tutto secondo i miei limiti. Poi voglio conoscere la dimensione di qualsiasi pulsante sullo schermo - lo faccio in "viewDidLayoutSubviews" e ottenere quel risultato nella console:

2014-10-29 12:27:09.088 Keyboard[2193:60674] view did layout subviews 
2014-10-29 12:27:09.088 Keyboard[2193:60674] {{inf, inf}, {0, 0}} 

Il pulsante ha la giusta dimensione e la posizione corretta, ma quando si cerca di ottenere il suo frame la dimensione non è impostata.

Dove devo inserire il mio codice quando non funziona in viewDidLayoutSubviews?

Ho trovato un sacco di domande su StackOverflow e altri siti Web, ma nessuno di questi ha coperto la mia domanda.

risposta

7

Sì! Ho risolto il problema da solo.

io non sono sicuro se ho capito bene, ma questo è quello che penso:

  • viewDidLayoutSubviews ottengono chiama ogni volta quando il layout sta cambiando
  • viewDidLayoutSubviews get chiamato quando il subviews diretti di il mio punto di vista era il layout, ma le sottoview di quelle sottoview non erano strutturate in quel momento, quindi non è possibile ottenere la dimensione di esse.

La mia soluzione era ora di chiamare manualmente .layoutSubviews() su tutte le mie opinioni, che contiene tutti i miei bottoni della tastiera. Dopo di ciò, ottengo la dimensione di tutti i pulsanti che voglio.

Per favore correggimi se sbaglio.

+1

ha funzionato per me, ma non so se è giusto. – JohnHanr

31

Ho riscontrato un problema molto simile (domanda potenziata) e ho trovato beeef's answer in modo che punti nella giusta direzione. Dato che la documentazione di Apple dice di non chiamare layoutSubviews() direttamente, ho invece fatto nel seguente modo (dove mySubView è una visualizzazione secondaria diretta di self.view):

override func viewDidLayoutSubviews() { 
    // self.view's direct subviews are laid out. 
    // force my subview to layout its subviews: 
    self.mySubView.setNeedsLayout() 
    self.mySubView.layoutIfNeeded() 

    // here we can get the frame of subviews of mySubView 
    // and do useful things with that... 
} 

Proprio A proposito, nel mio caso mySubView è un UIScrollView, e Ho bisogno di ottenere la cornice di una delle sue sottoview, in modo tale da poter impostare contentOffset di conseguenza prima che appaia la vista. Non sono sicuro che viewDidLayoutSubviews() sia il posto migliore per farlo, ma garantisce che mySubView sia stato progettato.

0

Mi sento sempre un po 'sporco quando si ricorre a DispatchQueue.asyncAfter() ma in questo caso è giustificato dal momento che viewDidLayoutSubviews viene chiamato prima che si verifichino tutte le regolazioni di AutoLayout nella gerarchia della vista. Lo preferisco a forzare un layout in più sincrono.

Problemi correlati