Je suis en train de construire un titleview avec des contraintes qui ressemble à ceci:Construire une titleview programmation avec des contraintes (ou la construction en général en vue des contraintes)
Je sais comment je ferais cela avec cadres. Je voudrais calculer la largeur du texte, la largeur de l'image, créer une vue avec cette largeur/hauteur pour contenir les deux, puis ajouter les deux sous-vues aux emplacements appropriés avec des cadres. J'essaie de comprendre comment on pourrait faire cela avec des contraintes. Ma pensée était que la taille intrinsèque du contenu m'aiderait ici, mais j'essaie désespérément de faire en sorte que cela fonctionne.
UILabel *categoryNameLabel = [[UILabel alloc] init];
categoryNameLabel.text = categoryName; // a variable from elsewhere that has a category like "Popular"
categoryNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[categoryNameLabel sizeToFit]; // hoping to set it to the instrinsic size of the text?
UIView *titleView = [[UIView alloc] init]; // no frame here right?
[titleView addSubview:categoryNameLabel];
NSArray *constraints;
if (categoryImage) {
UIImageView *categoryImageView = [[UIImageView alloc] initWithImage:categoryImage];
[titleView addSubview:categoryImageView];
categoryImageView.translatesAutoresizingMaskIntoConstraints = NO;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryImageView]-[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView, categoryNameLabel)];
} else {
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
}
[titleView addConstraints:constraints];
// here I set the titleView to the navigationItem.titleView
Je ne devrais pas avoir à coder en dur la taille de titleView. Elle devrait pouvoir être déterminée en fonction de la taille de son contenu, mais ...
- La propriété titleView détermine si sa taille est 0 sauf si je code en dur une trame.
- Si je mets
translatesAutoresizingMaskIntoConstraints = NO
les plantages d'applications avec cette erreur:'Auto Layout still required after executing -layoutSubviews. UINavigationBar's implementation of -layoutSubviews needs to call super.'
Mise à jour
Je l'ai à travailler avec ce code, mais je suis toujours avoir à définir le cadre de la titleview:
UILabel *categoryNameLabel = [[UILabel alloc] init];
categoryNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
categoryNameLabel.text = categoryName;
categoryNameLabel.opaque = NO;
categoryNameLabel.backgroundColor = [UIColor clearColor];
UIView *titleView = [[UIView alloc] init];
[titleView addSubview:categoryNameLabel];
NSArray *constraints;
if (categoryImage) {
UIImageView *categoryImageView = [[UIImageView alloc] initWithImage:categoryImage];
[titleView addSubview:categoryImageView];
categoryImageView.translatesAutoresizingMaskIntoConstraints = NO;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryImageView]-7-[categoryNameLabel]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView, categoryNameLabel)];
[titleView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[categoryImageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView)];
[titleView addConstraints:constraints];
titleView.frame = CGRectMake(0, 0, categoryImageView.frame.size.width + 7 + categoryNameLabel.intrinsicContentSize.width, categoryImageView.frame.size.height);
} else {
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
[titleView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[categoryNameLabel]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
[titleView addConstraints:constraints];
titleView.frame = CGRectMake(0, 0, categoryNameLabel.intrinsicContentSize.width, categoryNameLabel.intrinsicContentSize.height);
}
return titleView;
Votre code original n'a probablement pas fonctionné car vous n'aviez aucune contrainte dans l'axe vertical; votre seconde devrait être bien sans avoir à mettre des cadres. Que se passe-t-il si vous créez cette vue et que vous l'ajoutez ailleurs (plutôt que dans une barre de navigation, ce qui peut entraîner une complexité supplémentaire). – jrturton
J'essaye de réaliser ceci sans définir le cadre mais je n'ai pas pu trouver qui est le parent de la vue de titre dans lequel nous sommes censés ajouter les contraintes ... –
Le parent de la vue est le 'UINavigationBar' lui-même - mais vous êtes pas autorisé à ajouter des contraintes pour une raison quelconque - échouer avec 'Impossible de modifier les contraintes pour UINavigationBar géré par un contrôleur'. – Petar