Modifica: Utilizzando il nuovo concetto di Size Classes introdotto in Xcode 6, è possibile impostare facilmente diversi vincoli per classi di dimensioni specifiche in Interface Builder. La maggior parte dei dispositivi (ad esempio tutti gli iPhone attuali) hanno una classe di dimensioni verticale Compact in modalità orizzontale.
questo è un concetto molto meglio per le decisioni di layout generali di determinare l'orientamento del dispositivo.
Detto questo, se è davvero necessario conoscere l'orientamento, UIDevice.currentDevice().orientation
è la strada da percorrere.
Original post:
l'override del metodo di UIViewController
updateViewConstraints
per fornire i vincoli di layout per situazioni specifiche. In questo modo, il layout è sempre impostato correttamente in base alla situazione. Assicurati che formino un insieme completo di vincoli con quelli creati nello storyboard. È possibile utilizzare IB per impostare i propri vincoli generali e contrassegnare gli oggetti da modificare da rimuovere in fase di runtime.
Io uso la seguente implementazione di presentare un diverso insieme di vincoli per ogni orientamento:
-(void)updateViewConstraints {
[super updateViewConstraints];
// constraints for portrait orientation
// use a property to change a constraint's constant and/or create constraints programmatically, e.g.:
if (!self.layoutConstraintsPortrait) {
UIView *image1 = self.image1;
UIView *image2 = self.image2;
self.layoutConstraintsPortrait = [[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[image1]-[image2]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(image1, image2)] mutableCopy];
[self.layoutConstraintsPortrait addObject:[NSLayoutConstraint constraintWithItem:image1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem: image1.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
[self.layoutConstraintsPortrait addObject:[NSLayoutConstraint constraintWithItem:image2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:image2.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
}
// constraints for landscape orientation
// make sure they don't conflict with and complement the existing constraints
if (!self.layoutConstraintsLandscape) {
UIView *image1 = self.image1;
UIView *image2 = self.image2;
self.layoutConstraintsLandscape = [[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[image1]-[image2]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(image1, image2)] mutableCopy];
[self.layoutConstraintsLandscape addObject:[NSLayoutConstraint constraintWithItem:image1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:image1.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
[self.layoutConstraintsLandscape addObject:[NSLayoutConstraint constraintWithItem:image2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem: image2.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
}
BOOL isPortrait = UIInterfaceOrientationIsPortrait(self.interfaceOrientation);
[self.view removeConstraints:isPortrait ? self.layoutConstraintsLandscape : self.layoutConstraintsPortrait];
[self.view addConstraints:isPortrait ? self.layoutConstraintsPortrait : self.layoutConstraintsLandscape];
}
Ora, tutto quello che dovete fare è innescare un aggiornamento del vincolo ogni volta che la situazione cambia. Override willAnimateRotationToInterfaceOrientation:duration:
per animare l'aggiornamento vincolo sul cambiamento dell'orientamento:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.view setNeedsUpdateConstraints];
}
Non è necessario manualmente per "attivare" un aggiornamento dei vincoli. Il metodo 'updateViewConstraints' lo fa già. Questo commento è stato fatto anche da rokridi in basso, ma questa risposta non è stata modificata. –
Non dimenticare che il dispositivo potrebbe essere ruotato mentre la vista è in background. Potresti usare 'setNeedsUpdateConstraints' quando l'app è in primo piano. –
Con il rilascio di iOS 8 il concetto di * Size Classes * risolverà comunque questo problema;) – knl