iOS crée NSLayoutConstraint par programmation pour le contenu des cellules de vue de table

Je veux append dans le cellForRowAtIndexPath certaines vues à ma vue de contenu de cellule et pour elles des contraintes mais rien ne fonctionne. J'ai quelque chose comme ça:

NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:imageView atsortingbute:NSLayoutAtsortingbuteLeft relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteLeft multiplier:1.0f constant:10.0f]; [cell.contentView addConstraint:constraint]; 

Comment dois-je faire cela?

Quelques observations:

  1. Votre création de cette contrainte particulière est correcte. De toute évidence, vous ne pouvez pas simplement définir la contrainte de gauche, mais vous devez spécifier toutes les contraintes qui définiront sans ambiguïté l' frame des sous-vues de la cellule. Par exemple, définissez non seulement la contrainte de gauche (ou de début), mais également les contraintes de haut, de bas et de largeur. Ou définissez la contrainte de gauche plus les contraintes de largeur et de hauteur, et spécifiez la contrainte y verticale. Beaucoup de façons différentes de le faire, mais la key est que vous devez append toutes les contraintes qui définiront sans ambiguïté le frame de toutes les sous-vues.

    Par exemple, vous pourriez avoir quelque chose comme:

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSSsortingng *cellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; UIImageView *customImageView; UILabel *customLabel; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; customImageView = [[UIImageView alloc] init]; customImageView.translatesAutoresizingMaskIntoConstraints = NO; customImageView.tag = IMAGEVIEWTAG; [cell.contentView addSubview:customImageView]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView atsortingbute:NSLayoutAtsortingbuteLeading relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteLeft multiplier:1.0 constant:25.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView atsortingbute:NSLayoutAtsortingbuteWidth relatedBy:NSLayoutRelationEqual toItem:nil atsortingbute:NSLayoutAtsortingbuteNotAnAtsortingbute multiplier:1.0 constant:30.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView atsortingbute:NSLayoutAtsortingbuteTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteTop multiplier:1.0 constant:3.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView atsortingbute:NSLayoutAtsortingbuteBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteBottom multiplier:1.0 constant:-3.0]]; customLabel = [[UILabel alloc] init]; customLabel.translatesAutoresizingMaskIntoConstraints = NO; customLabel.tag = LABELTAG; [cell.contentView addSubview:customLabel]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel atsortingbute:NSLayoutAtsortingbuteLeading relatedBy:NSLayoutRelationEqual toItem:customImageView atsortingbute:NSLayoutAtsortingbuteTrailing multiplier:1.0 constant:10.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel atsortingbute:NSLayoutAtsortingbuteTrailing relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteTrailing multiplier:1.0 constant:-10.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel atsortingbute:NSLayoutAtsortingbuteTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteTop multiplier:1.0 constant:3.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel atsortingbute:NSLayoutAtsortingbuteBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView atsortingbute:NSLayoutAtsortingbuteBottom multiplier:1.0 constant:-3.0]]; } else { customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG]; customLabel = (id)[cell.contentView viewWithTag:LABELTAG]; } customImageView.image = ...; customLabel.text = ...; return cell; } 

    De toute évidence, vous utiliseriez fréquemment une sous-class UITableViewCell pour faciliter le suivi de vos controls personnalisés, mais je voulais garder l'exemple simple.

  2. Si vous n'êtes jamais sûr que les contraintes ont été définies sans ambiguïté, exécutez l'application et, une fois l'interface user présentée, suspendez l'application et entrez ce qui suit à l'invite (lldb) :

     po [[UIWindow keyWindow] _autolayoutTrace] 

    Cela vous informera si l'une des vues est définie de manière ambiguë (c'est-à-dire s'il manque des contraintes).

    Si vous voulez voir le frame de toutes les vues, vous pouvez entrer ce qui suit à l'invite (lldb) :

     po [[UIWindow keyWindow] recursiveDescription] 
  3. Assurez-vous de spécifier translatesAutoresizingMaskIntoConstraints à NO pour toutes les sous-vues, comme je l'ai fait dans l'exemple de code ci-dessus.

  4. Bien que vous puissiez définir les contraintes à l'aide de constraintWithItem , les gens utiliseront fréquemment constraintsWithVisualFormat , car vous pouvez souvent définir les contraintes de manière plus concise de cette façon. Comparez l'exemple de code ci-dessus avec cet exemple de code:

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSSsortingng *cellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; UIImageView *customImageView; UILabel *customLabel; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; customImageView = [[UIImageView alloc] init]; customImageView.translatesAutoresizingMaskIntoConstraints = NO; customImageView.tag = IMAGEVIEWTAG; [cell.contentView addSubview:customImageView]; customLabel = [[UILabel alloc] init]; customLabel.translatesAutoresizingMaskIntoConstraints = NO; customLabel.tag = LABELTAG; [cell.contentView addSubview:customLabel]; NSDictionary *views = NSDictionaryOfVariableBindings(customImageView, customLabel); [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-25-[customImageView(30)]-[customLabel]|" options:0 mesortingcs:nil views:views]]; [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customImageView]-3-|" options:0 mesortingcs:nil views:views]]; [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customLabel]-3-|" options:0 mesortingcs:nil views:views]]; } else { customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG]; customLabel = (id)[cell.contentView viewWithTag:LABELTAG]; } customImageView.image = ...; customLabel.text = ...; return cell; }