Je souhaite modifier les contraintes de mise en page lorsque l'appareil tourne. Mon UIViewController
est composé de 2 UIViews
, en paysage ils sont alignés horizontalement et en portrait ils sont alignés verticalement.
Cela fonctionne réellement, dans willAnimateRotationToInterfaceOrientation
, je supprime les contraintes souhaitées et les remplace par d'autres pour avoir la bonne disposition ...
Mais il y a des problèmes, pendant la rotation, la disposition automatique commence à briser les contraintes avant l'appel de willAnimateRotationToInterfaceOrientation
, alors où devons-nous remplacer nos contraintes lorsque la réorientation du périphérique se produit?
Un autre problème est la performance, après quelques rotations, le système ne rompt plus les contraintes, mais j'ai une énorme baisse de performance, surtout en mode portrait ...
Dans willRotateToInterfaceOrientation:duration:
, envoyez setNeedsUpdateConstraints
à toute vue dont les contraintes doivent être modifiées.
Sinon, créez une sous-classe UIView
. Dans votre sous-classe, inscrivez-vous pour recevoir UIApplicationWillChangeStatusBarOrientationNotification
. Lorsque vous recevez la notification, envoyez-vous setNeedsUpdateConstraints
.
Cela définit le drapeau needsUpdateConstraints
sur la vue. Avant que le système n'effectue la mise en page (en envoyant des messages layoutSubviews
), il envoie un message updateConstraints
à toute vue pour laquelle l'indicateur needsUpdateConstraints
est défini. C'est là que vous devez modifier vos contraintes. Créez une sous-classe UIView
et remplacez updateConstraints
pour mettre à jour vos contraintes.
Il y a une très bonne explication de la mise en page automatique et des rotations dans le post de Matthijs Hollemans. Vous pouvez le trouver ici: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
Habituellement, vous avez besoin d'environ 4 contraintes pour positionner correctement votre vue. Si mes vues ont une taille constante, je préfère épingler la hauteur et la largeur. Après cela, vous pouvez utiliser les contraintes d'espace Leading et Top pour faire ce que vous voulez. Par exemple, vous pouvez définir IBOutlets pour les contraintes d'espace de début et de fin pour vos vues:
@interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *_leadingSpaceConstraint;
IBOutlet NSLayoutConstraint *_topSpaceConstraint;
}
Ensuite, faites glisser la commande de la sortie vers votre contrainte. Vous pouvez maintenant modifier directement votre contrainte de vue à partir du code:
_leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE;
Pour valider vos modifications, vous devez appeler:
[self.view layoutIfNeeded];
Et si vous voulez le faire animé:
[UIView animateWithDuration:0.25
animations:^{
[self.view layoutIfNeeded];
}];
Je pense que cela fonctionnera dans willAnimateRotationToInterfaceOrientation, car vous n'avez pas besoin de briser les contraintes avec cette approche.
Un exemple: vous avez deux vues carrées en orientation portrait, l'une sous l'autre. Par exemple, définissez leurs contraintes "espace de tête sur superview" à 20. Ensuite, définissez "espace supérieur à la contrainte de superview" sur 20 pour la première vue et sur 120 pour la seconde. Ce sera notre configuration par défaut.
Ensuite, après la rotation, vous devez recalculer vos contraintes. Définissez maintenant les deux contraintes supérieures à 20 et les contraintes principales à 20 et 120 respectivement. Validez ensuite les modifications avec layoutIfNeeded.
J'espère que cela aidera.
remplacez -(void) viewWillLayoutSubviews
dans votre UIViewController
pour mettre à jour vos contraintes comme ci-dessous:
-(void) viewWillLayoutSubviews {
switch(self.interfaceorientation)
{
case UIInterfaceOrientationLandscapeLeft:
break;
case UIInterfaceOrientationLandscapeRight:
break;
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
}
}