J'utilise des contraintes de mise en page automatique par programme pour la mise en page de mes cellules UITableView personnalisées et je définis correctement les tailles de cellule dans tableView:heightForRowAtIndexPath:
Cela fonctionne très bien sur iOS6 et il fait regardez bien aussi dans iOS7
MAIS lorsque je lance l'application sur iOS7, voici le genre de message que je vois dans la console:
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2013-10-02 09:56:44.847 Vente-Exclusive[76306:a0b] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0xac4c5f0 V:|-(15)-[UIImageView:0xac47f50] (Names: '|':UITableViewCellContentView:0xd93e850 )>",
"<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>",
"<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>",
"<NSLayoutConstraint:0xac43680 V:[UIView:0xac4d0f0(1)]>",
"<NSLayoutConstraint:0xac436b0 V:[UIView:0xac4d0f0]-(0)-| (Names: '|':UITableViewCellContentView:0xd93e850 )>",
"<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>
Et en effet il y a une des contraintes de cette liste que je ne veux pas:
"<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>"
et je ne peux pas définir la propriété translatesAutoresizingMaskIntoConstraints
de la contentView
sur NO => cela endommagerait la cellule entière.
44 est la hauteur de cellule par défaut, mais j'ai défini mes hauteurs personnalisées dans le délégué de la vue tableau. Pourquoi la cellule contentView a-t-elle cette contrainte? Qu'est-ce qui pourrait causer ça?
Dans iOS6, cela ne se produit pas et tout semble aller pour iOS6 et iOS7.
Mon code est assez gros donc je ne le posterai pas ici, mais n'hésitez pas à demander une Pastebin si vous en avez besoin.
Pour spécifier comment je le fais, sur l'initialisation des cellules:
translatesAutoresizingMaskIntoConstraints
sur NOcontentView
de la cellulecontentView
Je suis également profondément intéressé à comprendre pourquoi cela se produit uniquement sur iOS7.
J'ai eu ce problème aussi .. Il semble que le cadre de contentView ne soit pas mis à jour tant que layoutSubviews
n'est pas appelé, mais le cadre de la cellule est mis à jour plus tôt, le cadre de contentView étant défini sur {0, 0, 320, 44}
au moment où les contraintes sont évaluées.
Après avoir examiné contentView de manière plus détaillée, il semble que le redimensionnement automatique des masques ne soit plus défini.
La définition du masque autoresizing avant de contraindre vos vues peut résoudre ce problème:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
if (self)
{
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[self loadViews];
[self constrainViews];
}
return self;
}
Apparemment, il y a quelque chose qui ne va pas avec UITableViewCell et UICollectionViewCell sur iOS 7 avec iOS 8 SDK.
Vous pouvez mettre à jour le contenu de la cellule lorsque la cellule est réutilisée comme ceci:
Pour Statable UITableViewController:
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
{
cell.contentView.frame = cell.bounds;
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
}
//your code goes here
return cell;
}
#endif
#endif
Étant donné que les contrôleurs de vue de table statique sont fragiles et peuvent facilement être cassés si vous implémentez des méthodes de source de données ou de suppression, certaines vérifications garantiront que ce code ne sera compilé et exécuté sur iOS 7.
Il en est de même pour UITableViewController dynamique standard:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = @"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
{
cell.contentView.frame = cell.bounds;
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
}
//your code goes here
return cell;
}
Dans ce cas, nous n'avons pas besoin de la vérification supplémentaire de la compilation, car l'implémentation de cette méthode est requise.
L'idée est la même dans les deux cas et pour UICollectionViewCell, comme indiqué dans ce fil de discussion: édition automatique du cadre de UICollectionViewCell contentView dans la cellule prototype de Storyboard (Xcode 6, iOS 8 SDK) lors de l'exécution sur iOS 7 uniquement
Lorsque les cellules sont réutilisées et que la hauteur peut changer en fonction du contenu, je pense qu'en général, il serait préférable de définir la priorité des espacements sur une valeur inférieure à celle requise.
Dans votre cas, UIImageView a un espacement de 15 vers le haut et la vue du bas a un espacement de 0 vers le bas. Si vous définissez la priorité de ces contraintes sur 999 (au lieu de 1 000), l'application ne plantera pas, car les contraintes ne sont pas obligatoires.
Une fois la méthode layoutSubviews appelée, la hauteur de la cellule sera correcte et les contraintes pourront être satisfaites normalement.
Je n'ai toujours pas trouvé de bonne solution pour les storyboards ... Quelques informations également ici: https://github.com/Alex311/TableCellWithAutoLayout/commit/bde387b27e33605eeac3465475d2f2ff9775f163#commitcomment-4633188
D'après ce qu'ils conseillent là-bas:
self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);
J'ai induit ma solution:
.
<tableView hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="44" ...
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ChatMessageCell" id="bCG-aU-ivE" customClass="ChatMessageCell">
<rect key="frame" x="0.0" y="22" width="320" height="44"/>
.
Définir une priorité d’affichage supérieure à 750 et inférieure à 1 000 peut peut-être résoudre.
"<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>",
Il suffit d'augmenter la hauteur de cellule par défaut. Le problème est que le contenu de la cellule est supérieur à la taille de cellule par défaut (initiale), violant certaines contraintes de non-négativité jusqu'à ce que la cellule soit redimensionnée à sa taille réelle.
J'ai eu le même problème. Ma solution basée sur les autres ci-dessus:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// initialize my stuff
[self layoutSubviews]; // avoid debugger warnings regarding constraint conflicts
}
return self;
}
Meilleur, Alessandro
J'ai fini par ne pas utiliser UITableViewCell dans le concepteur ... Je crée une vue personnalisée et l'ajoute par programme à la vue du contenu de la cellule ... Avec certaines catégories d'aide, il n'y a pas non plus de code "warmplate" ...
J'ai également fait face à ce problème et aucune des suggestions n'a aidé. Dans mon cas, j'avais une cellule de sélection de taille, et elle contenait collectionView à l'intérieur (chaque cellule collectionView contenait une image en taille réelle). Maintenant, la taille de la cellule était un peu plus grande (60) que la collectionView (50) et les images qu’elle contient (50). En raison de cette vue collectionView, la contrainte d'alignement bottom to superview avec une valeur de 10. Cela m'a donné un avertissement, et le seul moyen de résoudre ce problème était de rendre la hauteur de la cellule identique à celle de sa collectionView.
Si cela fonctionne correctement dans iOS8 et que l'avertissement apparaît dans iOS7, vous pouvez effectuer une recherche dans le code source du storyboard et trouver le bon tableauviewCell, puis ajouter l'attribut rect après la ligne tableviewCell. Merci à kuchumovn .
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" .../>
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>