web-dev-qa-db-fra.com

Puis-je désactiver l'autolayout pour une sous-vue spécifique lors de l'exécution?

J'ai une vue dont le cadre doit être manipulé par programme - c'est une sorte de vue de document qui englobe son contenu, qui est ensuite défilé et zoomé autour d'un survol en manipulant le cadre Origine. Autolayout se bat avec cela au moment de l'exécution.

Désactiver complètement l'autolayout semble un peu dur car cela pourrait raisonnablement être utilisé pour gérer la mise en page des autres vues. Il me semble que ce que je pourrais vouloir est une sorte de "contrainte nulle".

98
terriblememory

J'ai eu le même problème. Mais je l'ai résolu. 
Oui, vous pouvez désactiver la disposition automatique au moment de l’exécution pour une UIView spécifique, au lieu de la désactiver pour l’ensemble du xib ou du storyboard défini par défaut dans Xcode 4.3 ou version ultérieure.

Définissez translatesAutoresizingMaskIntoConstraints sur YES avant de définir le cadre de votre sous-vue:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);
164

J'avais un problème similaire où Autolayout remplaçait certains de mes réglages de cadre lors de l'exécution (j'avais une vue dynamique qui poussait parfois un nouveau contrôleur de vue ... Pousser puis appuyer sur Retour réinitialisait la vue initiale).

J'ai contourné cela en plaçant mon code de manipulation dans viewDidLayoutSubviews de mon contrôleur View. Cela semble être appelé après n'importe quelle contrainte appelée par mojo, mais avant viewDidAppear, l'utilisateur n'est donc pas le plus sage.

49
jmstone617

Le fait de définir translatesAutoresizingMaskIntoConstraints sur YES (sans ajouter de contraintes supplémentaires affectant cette vue) vous permettra de définir le cadre sans combattre le système de présentation automatique.

26
Jon Hull

Dans iOS 8, vous pouvez définir une contrainte NSLayoutConstraint pour qu'elle soit active ou non. Donc, si j'utilise un générateur d'interface, j'ajoute toutes mes contraintes à un OutletCollection, puis j'active ou désactive à l'aide de:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

L'application particulière pour laquelle je l'utilise ici a différentes contraintes en mode portrait et paysage et j'active/désactive en fonction de la rotation de l'appareil. Cela signifie que je peux créer des modifications de disposition complexes dans le générateur d’interface pour les deux orientations, tout en utilisant la présentation automatique sans le code de présentation automatique détaillé. 

Ou vous pouvez activer/désactiver en utilisant removeConstraints et addConstraints. 

17
bandejapaisa

Je ne sais pas si cela aidera quelqu'un d'autre, mais j'ai écrit une catégorie pour que cela soit pratique, car je me retrouve souvent à le faire.

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

Je l'utilise comme ça:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

J'espère que ça aide.

8
michaelsnowden

Vous pouvez définir le type translatesAutoresizingMaskIntoConstraints de type Boolean, valeur Oui dans les attributs d'exécution définis par l'utilisateur de UIView que vous souhaitez dans le scénario xib/storyboard.

6
renaun

Pour moi, cela a fonctionné pour créer la sous-vue par programme, dans mon cas, la présentation automatique jouait avec une vue que je devais faire pivoter autour de son centre mais une fois que j'ai créé cette vue par programme, cela fonctionnait.

1
Andrespch

À mon avis, j'avais une étiquette et un texte. L'étiquette avait un geste panoramique. L'étiquette se déplace bien pendant le glissement. Mais lorsque j'utilise le clavier de la zone de texte, l'étiquette redéfinit sa position sur l'emplacement d'origine défini dans la mise en page automatique. Le problème a été résolu lorsque j'ai ajouté le texte suivant dans Swift pour l'étiquette. J'ai ajouté ceci dans viewWillAppear mais il peut être ajouté à peu près n'importe où vous avez accès au champ cible.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true
1
Big D
  • Projet ouvert dans 4.5
  • Sélectionnez le storyboard
  • Ouvrir l'inspecteur de fichier
  • Dans le document Interface Builder Document, décochez la case "Utiliser autolayout".

Vous pouvez fractionner plusieurs story-boards si vous souhaitez utiliser l'autolayout pour certaines vues.

1
Mike Bobbitt

J'ai rencontré un scénario similaire dans lequel je rejoignais un projet initié avec la mise en page automatique, mais je devais apporter des ajustements dynamiques à plusieurs vues. Voici ce qui a fonctionné pour moi:

  1. Ne pas avoir des vues ou des composants présentés dans le constructeur d'interface.

  2. Ajoutez vos vues purement par programme en commençant par alloc/init et en définissant leurs cadres de manière appropriée.

  3. Terminé.

0
Yup.

Cela m'est arrivé dans un projet sans storyboards, ni fichiers xib. Tout code 100%. J'avais une bannière publicitaire en bas et je voulais que les limites de la vue s'arrêtent à la bannière publicitaire. La vue se redimensionnerait automatiquement après le chargement. J'ai essayé toutes les résolutions sur cette page, mais aucune d'entre elles n'a fonctionné. 

J'ai fini par créer simplement une vue secondaire avec la hauteur réduite et je l'ai placée dans la vue principale du contrôleur. Ensuite, tout mon contenu est entré dans la vue secondaire. Cela résout le problème très facilement sans rien faire qui semble aller à contre-courant.

Je pense que si vous voulez une vue qui n’est pas la taille normale qui remplit la fenêtre, vous devriez utiliser une vue secondaire pour cela.

0
RandallTo

Au lieu de désactiver l'autolayout, je calculerais simplement la nouvelle contrainte avec le cadre que vous remplacez. Cela me semble être le moyen approprié. Si vous ajustez des composants qui dépendent de contraintes, ajustez-les en conséquence. 

Par exemple, si vous avez une contrainte verticale de 0 entre deux vues (myView et otherView) et que vous avez un geste de panoramique ou quelque chose qui ajuste la hauteur de myView, vous pouvez alors recalculer la contrainte avec les valeurs ajustées.

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.Origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];
0
Myles Caley

Pour ceux d'entre vous qui utilisent la mise en page automatique, s'il vous plaît vérifier ma solution ici . Vous devriez créer @IBOutlet des contraintes que vous souhaitez ajuster, puis modifier leurs constantes.

0
Mike