Domanda

Ho una visualizzazione personalizzata che non funziona layoutSubview messaggi durante l'animazione.

Ho una vista che riempie lo schermo.Ha una visualizzazione secondaria personalizzata nella parte inferiore dello schermo che viene ridimensionata correttamente in Interface Builder se cambio l'altezza della barra di navigazione. layoutSubviews viene chiamato quando viene creata la vista, ma mai più.Le mie visualizzazioni secondarie sono disposte correttamente.Se disattivo la barra di stato delle chiamate, la visualizzazione secondaria è layoutSubviews non viene chiamato affatto, anche se la vista principale ne anima il ridimensionamento.

In quali circostanze è layoutSubviews effettivamente chiamato?

Io ho autoresizesSubviews impostato NO per la mia visualizzazione personalizzata.E in Interface Builder ho i montanti superiore e inferiore e il set di frecce verticali.


Un'altra parte del puzzle è che la finestra deve essere resa chiave:

[window makeKeyAndVisible];

altrimenti le visualizzazioni secondarie non vengono ridimensionate automaticamente.

È stato utile?

Soluzione 5

ho rintracciato la soluzione verso il basso per l'insistenza di Interface Builder che le molle non possono essere cambiati su una visione che ha gli elementi della schermata simulati accesi (barra di stato, ecc). Poiché le molle erano fuori per la visualizzazione principale, che guarda non potrebbe cambiare dimensioni e perciò fu scorrere giù nella sua interezza far della barra della chiamata.

Per quanto le caratteristiche simulate off, quindi il ridimensionamento della visualizzazione e impostando correttamente le molle causato l'animazione a verificarsi e il mio metodo da chiamare.

Un problema in più in debug questo è che il simulatore si chiude l'applicazione quando lo stato della chiamata viene attivata tramite il menu. Esci app = alcun debugger.

Altri suggerimenti

ho avuto una domanda simile, ma non ero soddisfatto con la risposta (o qualsiasi ho potuto trovare in rete), così ho provato nella pratica e qui è quello che ho ottenuto:

  • init non causa layoutSubviews a essere chiamato (duh)
  • cause addSubview: layoutSubviews di essere chiamato sul vista viene aggiunto, la vista è di essere aggiunto a (vista di destinazione), e tutti i subviews del target
  • vista setFrame le chiamate in modo intelligente su layoutSubviews la vista avendo suo telaio impostato solo se il parametro di dimensione del telaio è diverso
  • lo scorrimento di un UIScrollView cause layoutSubviews di essere chiamato su lo ScrollView, e la sua superview
  • rotanti un dispositivo solo chiamate layoutSubview sulla vista primaria (la viewControllers rispondono primaria view)
  • Il ridimensionamento di una vista chiamerà layoutSubviews sul suo superview

I miei risultati - http: // blog. logichigh.com/2011/03/16/when-does-layoutsubviews-get-called/

Basandomi sulla risposta precedente di @BadPirate, ho sperimentato ulteriormente e ho apportato alcuni chiarimenti/correzioni.l'ho trovato layoutSubviews: verrà chiamato in una vista se e solo se:

  • Propria limiti (non cornice) è cambiato.
  • I limiti di una delle sue sottoview dirette sono cambiati.
  • Una visualizzazione secondaria viene aggiunta o rimossa dalla visualizzazione.

Alcuni dettagli rilevanti:

  • I limiti si considerano modificati solo se il nuovo valore è diverso, compresa un'origine diversa.Nota in particolare ecco perché layoutSubviews: viene chiamato ogni volta che un UIScrollView scorre, poiché esegue lo scorrimento modificando l'origine dei suoi limiti.
  • La modifica del frame modificherà i limiti solo se la dimensione è cambiata, poiché questa è l'unica cosa propagata alla proprietà bounds.
  • Una modifica nei limiti di una vista che non è ancora in una gerarchia di viste risulterà in una chiamata a layoutSubviews: quando la vista viene infine aggiunta a una gerarchia di viste.
  • E solo per completezza:questi trigger no direttamente chiamare layoutSubviews, ma piuttosto chiamare setNeedsLayout, che imposta/alza una bandiera.Ogni iterazione del ciclo di esecuzione, per tutte le visualizzazioni nella gerarchia delle viste, questo flag è selezionato.Per ogni vista in cui si trova la bandiera alzata, layoutSubviews: viene richiamato e il flag viene reimpostato.Le viste più in alto nella gerarchia verranno controllate/chiamate per prime.

https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5- SW1

  

modifiche layout possono verificarsi ogni volta che uno dei seguenti eventi accade   in una vista:

     

a. La dimensione dei cambiamenti limiti del rettangolo di una vista.
  b. Un cambiamento di orientamento un'interfaccia si verifica, che di solito innesca un cambiamento della vista radice limiti rettangolo.
  c. L'insieme dei sottostrati Core Animation associati con i cambiamenti del livello della vista e richiede il layout.
  d. Il layout forze di applicazione si verifichi chiamando il metodo setNeedsLayout o layoutIfNeeded di vista.
  e. Il layout forze di applicazione chiamando il metodo setNeedsLayout dell'oggetto strato sottostante della vista.

Alcuni dei punti in di BadPirate risposta sono vero solo in parte:

  1. Per il punto addSubView

      

    addSubview provoca layoutSubviews da sollecitare la vista essendo aggiunta, la vista è stato aggiunto nel (vista di destinazione), e tutti i subviews del bersaglio.

    Dipende (vista di destinazione) maschera Dimensioni automatiche della vista. Se ha AutoResize maschera, layoutSubview sarà chiamato su ogni addSubview. Se non ha maschera AutoResize quindi layoutSubview verrà chiamato solo quando (obiettivo View) di dimensioni modifiche del telaio della vista.

    Esempio: se è stato creato UIView di programmazione (non ha maschera AutoResize per impostazione predefinita), LayoutSubview sarà chiamato solo quando UIView telaio non cambia su ogni addSubview

    .

    E 'attraverso questa tecnica che la prestazione dell'applicazione aumenta.

  2. Per il punto di rotazione del dispositivo

      

    rotazione di un dispositivo solo chiamate layoutSubview sulla vista principale (la risposta vista primaria del viewController)

    Questo può essere vero solo quando il VC è nella gerarchia VC (root al window.rootViewController), e questo è caso più comune. In iOS 5, se si crea un VC, ma questo non è aggiunto a qualsiasi altro VC, allora questo VC non otterrebbe alcun notato quando il dispositivo di rotazione. Pertanto la sua vista non si sarebbe accorto chiamando layoutSubviews.

chiamata [self.view setNeedsLayout]; in viewController rende chiamare viewDidLayoutSubviews

Hai guardato layoutIfNeeded?

Il frammento di documentazione è al di sotto. Fa il lavoro di animazione se si chiama questo metodo in modo esplicito durante l'animazione?

layoutIfNeeded Delinea le subviews se necessario.

- (void)layoutIfNeeded

Discussione Utilizzare questo metodo per forzare il layout di subviews prima di disegnare.

Disponibilità Disponibile in iPhone OS 2.0 e versioni successive.

Durante la migrazione di un'applicazione OpenGL da SDK 3-4, layoutSubviews non è stato chiamato più. Dopo un sacco di tentativi ed errori ho finalmente aperto MainWindow.xib, selezionato l'oggetto Window, nella finestra di ispezione ha scelto finestra Attributi scheda (più a sinistra) e controllati "Visibile al momento del lancio". Sembra che in SDK 3 è ancora usato per causare una chiamata layoutSubviews, ma non in 4.

6 ore di frustrazione messi alla fine.

Un caso piuttosto oscuro, ma potenzialmente importante quando layoutSubviews non viene mai chiamato è:

import UIKit

class View: UIView {

    override class var layerClass: AnyClass { return Layer.self }

    class Layer: CALayer {
        override func layoutSublayers() {
            // if we don't call super.layoutSublayers()...
            print(type(of: self), #function)
        }
    }

    override func layoutSubviews() {
        // ... this method never gets called by the OS!
        print(type(of: self), #function)
    }
}

let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top