Je veux ajouter dans le cellForRowAtIndexPath quelques 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
attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:10.0f];
[cell.contentView addConstraint:constraint];
Comment dois-je procéder?
Quelques observations:
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é le 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 verticale y. Beaucoup de façons différentes de le faire, mais la clé est que vous devez ajouter toutes les contraintes qui définiront sans ambiguïté le frame
de toutes les sous-vues.
Par exemple, vous pourriez avoir quelque chose comme ceci:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *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
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:25.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:30.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:3.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeBottom
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
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:customImageView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:10.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:-10.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:3.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeBottom
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-classe UITableViewCell
pour faciliter le processus de suivi de vos contrôles personnalisés, mais je voulais garder l'exemple simple.
Si vous n'êtes jamais sûr de savoir si les contraintes ont été définies sans ambiguïté, exécutez l'application et une fois l'interface utilisateur présentée, mettez l'application en pause et entrez ce qui suit dans le (lldb)
Invite:
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 ce que le frame
est pour toutes les vues, vous pouvez entrer ce qui suit dans le (lldb)
Invite:
po [[UIWindow keyWindow] recursiveDescription]
Assurez-vous de spécifier translatesAutoresizingMaskIntoConstraints
à NO
pour toutes les sous-vues, comme je l'ai fait dans l'exemple de code ci-dessus.
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 NSString *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 metrics:nil views:views]];
[cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customImageView]-3-|" options:0 metrics:nil views:views]];
[cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customLabel]-3-|" options:0 metrics:nil views:views]];
}
else {
customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG];
customLabel = (id)[cell.contentView viewWithTag:LABELTAG];
}
customImageView.image = ...;
customLabel.text = ...;
return cell;
}