2012-11-01 12 views
7

Quando sottoclasse UIView, di solito inserisco tutti i miei codici di inizializzazione e layout nel suo metodo init. Ma mi è stato detto che il codice di layout dovrebbe essere eseguito ignorando layoutSuviews. C'è un post su SO che spiega quando viene chiamato il metodo, ma mi piacerebbe sapere come usarli in pratica.UIView: layoutSubviews vs initWithFrame

Io attualmente messo tutto il mio codice nel metodo init, in questo modo:

MyLongView.m

- (id)initWithHorizontalPlates:(int)theNumberOfPlates 
{ 
    self = [super initWithFrame:CGRectMake(0, 0, 768, 1024)]; 

    if (self) { 
     // Initialization code 
     _numberOfPlates = theNumberOfPlates; 

     UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.frame]; 
     [scrollView setContentSize:CGSizeMake(self.bounds.size.width* _numberOfPlates, self.bounds.size.height)]; 
     [self addSubview:scrollView]; 

     for(int i = 0; i < _numberOfPlates; i++){ 
      UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"a1greatnorth_normal_%d.jpg", i+1]]; 
      UIImageView *plateImage = [[UIImageView alloc] initWithImage:img]; 
      [scrollView addSubview:plateImage]; 
      plateImage.center = CGPointMake((plateImage.bounds.size.width/2) + plateImage.bounds.size.width*i, plateImage.bounds.size.height/2); 
     } 

    } 
    return self; 
} 

Sono i soliti compiti: l'impostazione sulla struttura della vista, inizializzando un Ivar, impostando su una scrollview, inizializzando UIImages, posizionandoli in UIImageViews, disponendoli.

La mia domanda è: quale di questi dovrebbe essere fatto in init e quale di questi dovrebbe essere fatto in layoutSubviews?

risposta

15

L'init deve creare tutti gli oggetti, con i dati richiesti. Ogni frame che passi a loro in init dovrebbe idealmente essere la loro posizione di partenza.

Quindi, all'interno di layoutSubviews: si cambiano i frame di tutti gli elementi per posizionarli dove dovrebbero andare. No alloc'ing o init'ing dovrebbe avvenire in layoutSubviews :, solo il cambio delle loro posizioni, dimensioni ecc ...

4

Nel caso vi stiate ridimensionamento automatico funziona perfettamente con solo autoresizingFlags, o AutoLayout, si può basta usare init per impostare l'intera vista.

Tuttavia, in generale, è necessario eseguire il layout in LayoutView, poiché questo verrà richiamato ad ogni modifica del frame delle viste e in altre situazioni, in cui il layout sarà nuovamente necessario. A volte semplicemente non si conosce il frame finale di una vista in init, quindi è necessario essere flessibili come accennato, o usare layoutSubviews, poiché si esegue il layout lì dopo che è stata impostata la dimensione finale.

Come menzionato da WDUK, tutta la creazione di codice/oggetto di inizializzazione deve essere nel metodo init o ovunque, ma non in layoutSubviews.

+2

Lo spingerei più in basso. Crea i tuoi oggetti subview in 'viewDidLoad' piuttosto che init. le visualizzazioni vengono caricate pigramente e non vi è alcun motivo per creare visualizzazioni secondarie se la superview non verrà creata. – Abizern

+9

Stiamo parlando di viste qui, non di ViewController. – calimarkus

Problemi correlati