2013-07-17 14 views
11

Se sto implementando AutoLayout in modo programmatico su iOS, è corretto utilizzare il metodo initWithFrame? Se non come inizializzare una vista della dimensione preferita?Layout automatico usando initWithFrame?

+1

è ancora possibile utilizzare 'initWithFrame' – MZimmerman6

+0

Grazie MZimmerman6. Dovremmo evitare tale codifica o è corretto? Questo è il mio dubbio. – Arock

+0

Indipendentemente dal fatto che funzioni correttamente, per qualcosa di semplice, basta usarlo se è quello che ti piace con – MZimmerman6

risposta

3

Meglio evitare initWithFrame a meno che non si abbia scelta. Con Auto Layout, l'approccio consiste nel definire due vincoli che specificano larghezza e altezza. Esistono diversi modi per farlo, ma se lo stai programmaticamente, nel metodo updateViewConstraints del tuo controller di visualizzazione o nel metodo updateConstraints della vista, verifica se i vincoli sono già stati creati e, in caso contrario, aggiungili alla tua vista.

E.g.

[myConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_mySubView]-(200)-|" 
           options:0 
           metrics:nil 
           views:_myViewsDictionary]]; 

[myConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_mySubView(100)]-|" 
           options:0 
           metrics:nil 
           views:_myViewsDictionary]]; 

Detto questo, è meglio farlo utilizzando Interface Builder. Una volta che ci si abitua - e ci vuole un po 'per abituarsi - lo troverete un fantastico risparmio di tempo e molto meglio che definire i vostri vincoli nel codice.

+0

Questo non è davvero convincente per me. Sono d'accordo che è sciocco definire un frame quando non lo si utilizzerà, ma Apple continua a dire che 'initWithFrame' è l'inizializzatore designato per la classe' UIView' nella documentazione. Chiamare 'init' invece sembra funzionare bene, ma temo che potrebbe non essere il caso nelle future versioni di iOS. –

+0

se si utilizza init, l'UIView verrà inizializzato tramite initWithFrame ma con un parametro CGRectZero. Quindi, stai facendo effettivamente la stessa cosa. Quale frame fornirai a initWithFrame? Una cornice che non verrà utilizzata?Puoi anche passare CGRectZero, che è esattamente quello che faresti se usassi init inizialmente. Ha molto più senso con Auto Layout dove, come hai notato, il frame verrà ignorato. In Swift farai un sacco di UIView(). –

+0

Questo sembra essere assolutamente quello che il metodo 'init' non documentato fa oggi, ma dal momento che il comportamento di' [UIView init] 'non è documentato, potrebbe non essere vero in iOS 9, a quel punto il codice esistente potrebbe interrompersi. Sono completamente d'accordo sul fatto che passare un frame è stupido e che chiamare 'init' funziona bene oggi, ma questo non cambia il fatto che Apple non abbia documentato questo comportamento. Poiché la domanda era quale fosse la via "corretta", non sono sicuro che la risposta sia "fare affidamento su comportamenti non documentati". –

0

Perché non solo: myView = [UIView new];

È uguale a myView = [[UIView alloc] init]; Funzionerà nel tuo caso se poi ad un certo punto aggiungi i vincoli richiesti.

+0

È necessario aggiungerlo come commento. O aggiungere ulteriori spiegazioni perché questo dovrebbe funzionare. –

+0

Ho modificato la mia risposta. – Ricardo

0
override init(frame: CGRect) { 
    super.init(frame: frame) 
    NSBundle.mainBundle().loadNibNamed("YourView", owner: self, options: nil) 
    self.containerView.frame = CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)) 
    self.addSubview(self.containerView) 
} 

Questo è quello che faccio adesso. Lavoro con un po 'di codice legacy e a volte mi viene richiesto molto tempo per convertire tutto per usare l'autolayout. Ancora una volta, come dichiarato da @Max MacLeod, non usare questo a meno che non si abbia scelta.

+0

Vorrei aggiungere che ho ancora un pennino per la mia vista. –

Problemi correlati