2015-02-01 13 views
10

Quando si utilizza il layout automatico in uno storyboard, esiste un'opzione per mantenere un vincolo installato o meno con una casella di controllo "Installata". Disabilitarlo farà sì che si comporti come se non avessi aggiunto quel vincolo - non avrebbe alcun effetto. È possibile configurare lo stato installato per classi di dimensioni diverse in Interface Builder e modificare questo valore a livello di codice impostando la proprietà active su true o false.Dove cambiare "installato" per il vincolo di Layout automatico?

Nella mia app voglio avere un vincolo installato solo mentre il dispositivo è in verticale - dovrebbe essere "disinstallato" quando si ruota in orizzontale. Questo può essere fatto per gli iPhone deselezionando installato per Any Width Compact Height. (Anche se non sembra funzionare correttamente perché rompe questo vincolo a causa di vincoli conflittuali quando ruota verso il paesaggio quando non dovrebbe nemmeno essere installato, ma indipendentemente dall'interfaccia utente appare sempre come previsto.) Ma non c'è modo di disinstallare il vincolo per l'iPad in orizzontale in Interface Builder (è Regular Width Regular Height in entrambi gli orientamenti).

Dove è il posto giusto per abilitare/disabilitare active per NSLayoutConstraint s quando si ruota il dispositivo? In che modo il metodo di rotazione che modifica lo stato ha come risultato il comportamento desiderato, solo per l'impostazione verticale? Se tale metodo non viene richiamato all'avvio dell'app, in quale altro metodo deve essere inserito oltre a un metodo di rotazione?

Ho provato inserendo il seguente codice nella viewDidLoad e viewWillTransitionToSize, ma questo si traduce in un comportamento imprevisto durante l'esecuzione su iPad:

  • lanciare l'applicazione nel paesaggio fa sì che il vincolo di essere attivo, nonostante il fatto attiva è stato impostato su false, interrompe il vincolo e l'interfaccia utente non viene visualizzata come previsto
  • Avvio dell'app in portrait set attivo su true (era già installato in IB) quindi funziona come previsto
  • Avvio dell'app in verticale e ruotando il dispositivo in orizzontale funziona come previsto - il vincolo è impostato su inattivo, non interrompe il vincolo, l'interfaccia utente viene visualizzata come previsto
  • L'avvio dell'app in verticale, la rotazione in orizzontale e il ritorno in verticale rendono l'interfaccia utente corretta ma interrompe questo vincolo che è impostato su attivo

Se si disinstalla il vincolo in Interface Builder, quindi eseguo gli scenari di cui sopra, ottengo essenzialmente il comportamento opposto.

if size.width > size.height { 
    self.myConstraint.active = false 
} else { 
    self.myConstraint.active = true 
} 

risposta

0

Sono un po 'tardi per rispondere, ma qui è il mio 2 centesimi quando ho affrontato un problema simile a risolvere il problema dell'incapacità di Autolayout per rilevare Compact larghezza/altezza compatto per iPhone con iOS 7. Non c'è la proprietà activated in iOS 7, quindi ho dovuto aggiungerli/rimuoverli.

Ho creato due metodi per aggiungere e rimuovere i vincoli e questi vincoli sono già impostati su IB e li faccio riferimento con le proprietà di IBOutlet. Quindi, dal momento che li rimuovo, a differenza di altri oggetti IB, dovrei impostarli su strong, non su weak. Altrimenti, una volta rimossi saranno distrutti e non potrò più farvi riferimento per riaggiungerli.

Ecco il mio metodo vincolo di rimozione:

-(void)removeiOS7andiPhone4inLandscapeToOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ 

    if(!UIInterfaceOrientationIsLandscape(toInterfaceOrientation)&&(NSFoundationVersionNumber<=NSFoundationVersionNumber_iOS_7_1)&&(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)){ 
     // if iPhone with iOS 7 on portrait remove Constraints here 

    } 
} 

e qui è il metodo vincolo vipera:

-(void)addiOS7andiPhone4inLandscapeToOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ 

    if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)&&(NSFoundationVersionNumber<=NSFoundationVersionNumber_iOS_7_1)&&(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)){ 
     // if iPhone with iOS 7 on landscape add Constraints here 

    } 

} 

Per quanto riguarda dove chiamare questi metodi, come si è tentato, chiamare tutti e due in viewWillAppear (non è necessario chiamare viewWillDisappear) e viewWillTransitionToSize (nel mio caso questo è willRotateToInterfaceOrientation, poiché viewWillTransitionToSize è disponibile solo dopo iOS 8). Chiamarli successivamente ha senso, dopotutto solo uno di essi verrà eseguito a causa del controllo del loro orientamento verticale/orizzontale con if, prima di apportare le modifiche necessarie.

e qui è la mia definizione willRotateToInterfaceOrientation metodo:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 

    // this will be run only if orientation is on Portrait 
    [self addiOS7andiPhone4inLandscapeToOrientation:toInterfaceOrientation]; 

    // this will be run only if orientation is on Landscape 
    [self removeiOS7andiPhone4inLandscapeToOrientation:toInterfaceOrientation]; 
} 

ed effettuare una chiamata simile in viewWillAppear.

AVVISO: assicurarsi di eseguire esattamente l'opposto in questi metodi e non aggiungere necessariamente vincoli solo in addConstraintMethod e rimuovere solo in removeConstraintMethod. Nel mio caso, aggiungo e rimuovo entrambi i vincoli in ognuno di essi, quindi i nomi dei metodi non riflettono esattamente il vero ruolo di essi, ma finché si fanno gli opposti esatti, si è pronti.

Problemi correlati