iOS: multiligne uilabel ne montre qu'une seule ligne avec autolayout

Le code ci-dessous, je pense devrait résulter dans une label multiligne suivie d'un button, cependant, après la layout, il n'y a qu'une seule ligne de l'label apparaissant. Alors que je pourrais mettre une hauteur explicite dans la disposition verticale qui irait à l'encontre du but. Des idées sur les autres contraintes que je devrais appliquer?

UILabel *lbExplain = [[UILabel alloc] init]; lbExplain.text = @"The Sync process allows you to synchronize your library between different devices. By clicking on the button below you can find other devices to sync with. The other device also has to be running this applicaton."; lbExplain.lineBreakMode = NSLineBreakByWordWrapping; lbExplain.numberOfLines = 0; lbExplain.translatesAutoresizingMaskIntoConstraints = NO; UIButton *btnPartner = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btnPartner setTitle:@"Look for Partners" forState:UIControlStateNormal]; [btnPartner addTarget:self action:@selector(findPartners:) forControlEvents:UIControlEventTouchUpInside]; btnPartner.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:lbExplain]; [self.view addSubview:btnPartner]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[lbExplain]-|" options:0 mesortingcs:nil views:NSDictionaryOfVariableBindings(lbExplain)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[lbExplain]-[btnPartner]" options:NSLayoutFormatAlignAllLeft mesortingcs:nil views:NSDictionaryOfVariableBindings(lbExplain, btnPartner)]]; 

Ajouter la ligne:

 lbExplain.preferredMaxLayoutWidth = 280; 

Cela doit être quelque chose qui est fait automatiquement dans IB, puisque l'label se développe correctement si vous l'installez là-bas. Le nombre que vous lui transmettez semble importer dans la façon dont il se développe verticalement, mais il ne remplace pas les contraintes que vous définissez pour la largeur.

Après l'édition:

Cela fonctionne mieux si j'ajoute cette ligne dans updateViewConstraints, et relie le nombre aux limites de la vue. De cette façon, il s'adapte correctement à la rotation.

 -(void)updateViewConstraints { [super updateViewConstraints]; lbExplain.preferredMaxLayoutWidth = self.view.bounds.size.width - 40; } 

Le problème ici est que preferredMaxLayoutWidth n'est pas défini. Par conséquent, le text n'est limité par aucune largeur et, en tant que tel, il ne passe pas à la ligne suivante.

J'ai trouvé que la façon la plus simple d'utiliser un multiligne UILabel avec Autolayout est de créer une sous-class:

 @interface MyMultilineLabel : UILabel @end @implementation MyMultilineLabel - (void)setBounds:(CGRect)bounds { [super setBounds:bounds]; CGFloat width = CGRectGetWidth(bounds); if (self.preferredMaxLayoutWidth != width) { self.preferredMaxLayoutWidth = width; } } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.lineBreakMode = NSLineBreakByWordWrapping; self.numberOfLines = 0; } return self; } @end 

Etes-vous sûr que vous n'avez pas de layout ambiguë?

vous pouvez faire un test dans votre code comme

 if ([self.view hasAmbiguousLayout]) { NSLog(@"ambiguous"); } 

ou faites une pause sur le simulateur ou le dispositif de test et tapez dans la console:

 po [[UIWindow keyWindow] _autolayoutTrace] 

si c'est le cas, vous pourriez essayer de rendre vos contraintes un peu plus explicites (à première vue, la hauteur est ambiguë):

 @"V:|-[lbExplain]-[btnPartner]-|" 

ou

 @"V:|-[lbExplain(==300)]-[btnPartner(==200)]" 

voici la documentation pour le langage de format visuel:

http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html

J'ai eu un problème similaire, où une label multiligne dans un UITableViewCell, positionné avec AutoLayout, ne se développerait pas elle-même.

Il était à l'intérieur d'un UITableView gestion des tailles «automatiquement» avec UITableViewAutomaticDimension et méthode estiméHeightForRowAtIndexPath . (Je pense que c'est peut-être la source du problème)

J'ai compris ce problème en appelant:

 [cell layoutIfNeeded] 

dans la méthode cellForRowAtIndexPath , juste avant de renvoyer la cellule.

Et ça a fonctionné comme un charme !