2012-08-27 5 views
8

Quando chiamo sizeToFit su una delle mie visualizzazioni, ho notato che il framework iOS prima chiama sizeThatFits e quindi layoutSubviews su quella vista. Questo è un problema per me perché il calcolo nel mio sizeThatFits dipende dai risultati del mio layoutSubviews. Nell'esempio seguente, una sottoview viene regolata in layoutSubviews e l'altezza di questa sottoview viene utilizzata in sizeThatFits. Attualmente il mio codice non funziona, l'ordine è invertito.Come ottenere il layout delle immagini da chiamare prima di sizeThatFits?

In viewDidLoad di mio controller della vista:

UIView* header = [[MyHeader alloc] init]; 
[header sizeToFit]; 
self.tableView.tableHeaderView = header; 
[header release]; 

A mio avviso:

- (void) layoutSubviews { 
    [super layoutSubviews]; 
    [self.subView sizeToFit]; 
} 

- (CGSize) sizeThatFits:(CGSize)size { 
    return CGSizeMake(
     self.frame.size.width, 
     self.subView.frame.size.height 
    ); 
} 
+0

Hai mai risolto questo problema? –

+0

Nel tuo primo codice si chiama '[header sizeToFit]' che non fa nulla 'sizeThatFits:' MyHeader' non è sovrascritto: > L'implementazione predefinita di questo metodo restituisce la porzione di dimensioni del rettangolo dei limiti della vista. – Rivera

risposta

0

non puoi semplicemente modificare il telaio della visualizzazione secondaria nel metodo -layoutSubviews anziché il metodo -sizeThatFits:?

1

Hai provato a chiamare layoutIfNeeded per visualizzare layoutSubviews? Nonostante il nome fuorviante, questo è il modo per attivare immediatamente lo layoutSubviews. Prova a chiamare prima dello sizeToFit o sizeThatFits.

6

Si desidera che la propria vista faccia sempre la cosa giusta (tm), indipendentemente dall'ordine in cui si chiamano le cose. Per farlo, ti suggerisco di inserire il codice che calcola l'altezza desiderata per la tua vista e le sottoview in un metodo separato. Qualcosa in questo senso:

- (void)updateSubviewDimensions 
{ 
    [self.subview sizeToFit]; 
    // possibly much more code 
} 

- (void) layoutSubviews { 
    [super layoutSubviews]; 
    [self updateSubviewDimensions]; 
} 

- (CGSize) sizeThatFits:(CGSize)size { 
    [self updateSubviewDimensions]; 
    return CGSizeMake(
     self.frame.size.width, 
     self.subView.frame.size.height 
    ); 
} 

questo modo, non dipendono da ricordare di chiamare un certo metodo prima di chiamare sizeToFit, ma la vostra vista sarà sempre fare quello che vuoi. Inoltre, il tuo codice è meno fragile e più facile da capire quando lo guardi tra qualche mese (o chiedi a uno sviluppatore diverso di guardarlo).

+0

TL; DR: implementa 'updateConstraints' e chiama' updateSubviewDimensions'. Verbose: Non ho tempo per una risposta completa, ma penso che la soluzione corretta qui sia implementare updateConstraints. Dai test su iOS 8.3, l'implementazione UIView predefinita di systemLayoutConstraintsFittingSize richiama alla fine una chiamata a updateConstraints. Ciò fornisce al sistema AL tutto ciò di cui ha bisogno per determinare le dimensioni, senza dover necessariamente sistemare le cose. –

2

Se il vostro sizeThatFits: richiede che il layout sia accurato, è necessario forzare un layout (vedere il codice di seguito). Ma penso che questo sia progettato male perché il layout non tiene conto della "dimensione".

- (CGSize) sizeThatFits:(CGSize)size { 

    [self setNeedsLayout]; 
    [self layoutIfNeeded]; 

    return CGSizeMake(
     self.frame.size.width, 
     self.subView.frame.size.height 
    ); 
} 

Un approccio migliore potrebbe essere quella di utilizzare il layout automatico per l'subviews, quindi utilizzare systemLayoutSizeFittingSize: per determinare la dimensione necessaria della visualizzazione (vs. sizeThatFits:)

Se non si può o non si vuole per utilizzare il layout automatico, è necessario considerare percorsi di codice separati per il calcolo effettivo del layout e del layout.

1

Il problema qui è che le sottoview non hanno dimensioni fino a quando non viene chiamato layoutSubviews. È lo stesso di una cella di visualizzazione tabella personalizzata.

Per aggirare questo problema è necessario modificare la logica o eseguire autonomamente la matematica per ottenere una dimensione esplicita senza fare affidamento su elementi automatici.

Problemi correlati