Utiliser la mise en page automatique pour définir dynamique UIView pour correspondre à conteneur de vue
J'ai une UIView de l'IB qui a un autre UIView l'intérieur d'elle, que je suis en utilisant un conteneur de vue. Dans le code, j'ai créer trois différents points de vue et puis d'animer le plus approprié dans le récipient de vue en fonction de l'état de l'application. Un seul des trois différents points de vue seront valables à un moment donné. Le problème c'est que quand je lance sur différentes iPhone dans le simulateur, mon nouveau sous-vues ne sont pas mis à l'échelle pour correspondre le conteneur de vue. Je suis en utilisant la mise en page automatique. Pour des fins de test, j'ai mis en place mon sous-vues à être juste un gros bouton qui a toutes ses bords contraint à l'superview. Et le conteneur de vue a aussi ses bords contraint à superview. Ce que je veux, c'est de la sous-vue de faire correspondre le conteneur de vue. j'.e le bouton s'étend sur la totalité de la taille du conteneur de vue. Lorsqu'il est exécuté sur différents iPhones de la taille du conteneur de vue et, par conséquent, la sous-vue doivent évoluer proportionnellement par rapport à l'autre iPhone de tailles d'écran.
Ci-dessous le code que j'utilise pour init mon sous-vue et de mettre en place de contraintes par rapport au conteneur vue.
UIView *containerView = self.subView;
UIView *newSubview = [[mySubview alloc] init];
[newSubview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.containerView addSubview:newSubview];
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:newSubview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.containerView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:newSubview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.containerView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:newSubview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.containerView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:newSubview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.containerView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]];
J'ai juste ne peut pas sembler obtenir que cela fonctionne. Je suis assez nouveau à mise en page automatique et ne suis pas sûr de ce que je fais de mal et pour cesser de se taper la tête contre ce mur. Toute aide serait formidable. 🙂
************* PLUS D'INFOS **************
Désolé, je n'ai pas déclaré mon problème aussi clairement que je pouvais avoir. Voici donc quelques infos avec des captures d'écran. Tout d'abord, je vais vous décrire ce que j'ai fait au niveau du code.
Dans didFinishLaunchingWithOptions dans AppDelegate.m, j'ai créer MyViewController comme ça,
self.myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
Dans le viewDidLoad dans MyViewController.m, j'ai créer mySubview et de l'ajouter à ma containerView et de créer des contraintes, comme cela,
UIView *containerView = self.containerView;
UIView *mySubview = [[MySubview alloc] init];
[mySubview setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:mySubview];
NSDictionary *views = NSDictionaryOfVariableBindings(mySubview);
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mySubview]|"
options:0
metrics:nil
views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mySubview]|"
options:0
metrics:nil
views:views]];
Et enfin dans l'init dans MySubview.h-je ajouter de la plume comme une sous-vue comme ça,
- (id)init
{
if(self = [super init])
{
NSArray *nibArray = [[NSBundle mainBundle]loadNibNamed:@"MySubview" owner:self options:nil];
[self addSubview:[nibArray objectAtIndex:0]];
}
return self;
}
Un couple de choses à noter qu'il peut aider,
Dans MyViewController.xib, j'ai une UIView que je suis en utilisant le containerView. Il a un IBOutlet de UIView* containerView est celui qui est mentionné ci-dessus. Les seules contraintes que j'ai pour le containerView de l'IB sont, de leader, de fuite et en bas de l'espace de Superview et supérieur de l'espace de Superview = 44.
Pour MySubview.xib, la hauteur et la largeur de 300, (pas de contraintes sont utilisées pour la hauteur ou la largeur). J'ai l'impression que ces tailles ne devrait pas d'importance depuis mySubview est censé être contraint de containerView.
Dans MySubview.xib, j'ai 3 objets, topButton: hauteur = 29, middleView: hauteur = 242 et bottomButton: hauteur = 29. (voir image jointe) TopButton a conduit, de fuite et de haut en Superview contraintes et un bas middleView contrainte. MiddleView a attaque et de fuite de Superview contraintes et un haut de topButton contrainte et un bas bottomButton contraintes. Et enfin bottomButton a la principale, arrière et bas de Superview contraintes et un haut de middleView contrainte.
Ce que je veux est pour mySubview à l'échelle pour s'adapter à la containerView depuis des contraintes ont été créer et ajouter mais au lieu de cela, mySubview devient très grande et clips containerView.
Voici quelques captures d'écran:
MyViewController.xib, le rectangle bleu en dessous du titre de mon conteneur vue et a la IBOutlet containerView.
MySubview.xib
Et enfin, le résultat, qui sont incorrectes.
Au lieu je voudrais que ce que j'ai faux juste pour obtenir la copie d'écran.
Sur l'iPhone 4,
De l'iPhone 5,
Comme vous pouvez le voir dans les fausses captures d'écran, mySubview échelle pour s'adapter à la containerView, de même que containerView échelles un peu pour s'ajuster à l'autre téléphone tailles d'écran.
Espère que je n'ai pas trop d'info. Toute aide serait formidable. Je sens que je suis proche, mais doit manquer une étape clé. Grrrrr.
Vous devez vous connecter pour publier un commentaire.
Un couple de pensées:
En fait cela a l'air bien, en dehors du nom de la variable d'étrangeté: Votre variable locale,
containerView
est égal àself.subView
, mais toutes les autres lignes se référer à une autre variable, à une propriété de classe,self.containerView
. Avez-vous omettez une ligne où vous définissez quecontainerView
des propriétés de la classe? Mais quand je le fixe, votre code a bien fonctionné pour moi.Assurez-vous que vous n'êtes pas essayer de regarder la
frame
immédiatement après la définition de contraintes, comme le changement ne sera pas encore être reflétés dans leframe
paramètres. Vous pouvez faire un[containerView layoutIfNeeded];
si vous voulez forcer la nouvelle disposition tout basée sur les contraintes. Aussi, si vous souhaitez confirmerframe
paramètres, il est préférable de reporter les valeurs jusqu'à ce que aprèsviewDidAppear
(c'est à direviewDidLoad
est trop tôt dans la vue processus de construction).Un mineur tweak sur votre code (et sans rapport avec votre problème), mais quand je suis les contraintes à l'intérieur d'un conteneur de vue, j'ai souvent non seulement
NSLayoutAttributeTop
etNSLayoutAttributeLeading
, comme vous l'avez fait, mais aussiNSLayoutAttributeBottom
etNSLayoutAttributeTrailing
(plutôt queNSLayoutAttributeWidth
etNSLayoutAttributeHeight
). Il accomplit la même chose que votre code, mais lors de l'utilisation des valeurs non nulles, c'est une fraction plus intuitive.De toute façon, j'ai juste fait le code suivant, la permutation de la vôtre, et il fonctionne très bien:
Vous pouvez simplifier ce code un peu à l'aide de format visuel de la langue, par exemple:
Je le trouve plus facile d'obtenir les contraintes de droite à l'aide de visual format de la langue. Un peu moins d'erreur (pour moi, au moins). Il ya, cependant, certaines contraintes qui ne peuvent être représentées dans un format visuel, de la langue, auquel cas je revenir à la syntaxe que vous décrivez.
Dans votre nouvelle question, vous nous montrez un
init
méthode pour votre sous-vue, qui ne un autreaddSubview
. Vous devez définir des contraintes, là aussi. Bas de ligne, où vous faireaddSubview
, vous devez définir vos contraintes, par exempleframe
paramètres immédiatement après la définition de contraintes, comme cela ne fonctionnera pas à moins que (a) vous le faites enviewDidAppear
ou plus tard; et/ou (b) vous forcelayoutIfNeeded
. Ligne de fond, comment avez-vous conclu que les contraintes ne sont pas de travail? Voir ma réponse révisée pour quelques autres observations.init
, vous êtes en train de faire l'autreaddSubview
. Donc, il suffit de répéter la contrainte processus de création, là aussi. Voir le point n ° 5 dans ma réponse révisée.Dans le problème de l'état "mon nouveau sous-vues ne sont pas mis à l'échelle pour correspondre le conteneur view" - mais à partir de la description que je pense qu'ils sont - le problème, c'est que votre conteneur de vue n'a pas de taille fixe.
Je pense que si vous réglez votre conteneur en vue de fixe, de la largeur et de la hauteur qui doit le faire, vous pouvez aussi avoir besoin d'appeler
à force de redimensionnement après la mise à jour des contraintes.
Je voudrais aussi vous suggère de swap à l'aide de la base de texte mise en forme, vous pouvez échanger vos lignes ci-dessus pour quelque chose comme "H:|[newSubview]|" et "V:|[newSubview]|"