Lignes d’ancrage UITableView au bas

J’ai un UITableView qui doit introduire un nouveau contenu à partir du bas. Voici comment une vue de table se comporte lorsque la vue est pleine et que vous ajoutez de nouvelles lignes avec une animation.

Je commençais par modifier le contentInset au fur et à mesure de l’introduction des lignes, mais lorsque les choses changent, l’animation des entrées est fausse… Mon problème avec cette approche est aggravé par le fait que les utilisateurs peuvent supprimer des lignes et la ligne mise à jour du contenu, ce qui entraîne leur redimensionnement (chaque ligne a sa propre hauteur qui change).

Toutes les recommandations sur la façon d’obtenir des lignes UITableView apparaissent toujours au bas de l’espace de vue de UITableView?

J’ai une solution qui fonctionne parfaitement pour moi, mais elle suscite beaucoup de double reflection, donc ce n’est pas aussi simple en théorie que dans la pratique …

Étape 1, appliquez une transformation à la vue de la table en la faisant pivoter de 180 °

tableView.transform = CGAffineTransformMakeRotation(-M_PI); 

Étape 2, faites pivoter votre cellule brute 180deg dans tableView: cellForRowAtIndexPath:

 cell.transform = CGAffineTransformMakeRotation(M_PI); 

Étape 3, inversez votre source de données. Si vous utilisez un NSMutableArray, insérez de nouveaux objects à l’emplacement 0 au lieu d’utiliser AddObject …

Maintenant, la partie la plus difficile est de se rappeler que la gauche est à droite et que la gauche est laissée au niveau de la table, donc si vous utilisez

 [tableView insertRowsAtIndexPaths:targetPath withRowAnimation:UITableViewRowAnimationLeft] 

il doit maintenant être

 [tableView insertRowsAtIndexPaths:targetPath withRowAnimation:UITableViewRowAnimationRight] 

et même pour les suppressions, etc.

Selon ce que votre magasin de données est, vous devrez peut-être gérer cela dans l’ordre inverse aussi …

Note: faites pivoter les cellules de manière OPPOSEE à la table, sinon la précision de la virgule flottante peut rendre la transformation parfaite et vous obtenez des crawlies sur certains graphiques de temps en temps lorsque vous faites défiler … mineures mais ennuyeuses.

La méthode acceptée introduit des problèmes pour mon application – la barre de défilement est du mauvais côté et il gèle les séparateurs de cellules pour UITableViewStyleGrouped

Pour résoudre ce problème, utilisez ce qui suit

 tableView.transform = CGAffineTransformMakeScale (1,-1); 

et

 cell.contentView.transform = CGAffineTransformMakeScale (1,-1); // if you have an accessory view cell.accessoryView.transform = CGAffineTransformMakeScale (1,-1); 

Une approche similaire à ima747, mais tournant à 180 degrés, fait également passer l’indicateur de défilement du côté opposé. Au lieu de cela, j’ai inversé la vue de la table et ses cellules verticalement.

 self.tableView.transform = CGAffineTransformMakeScale(1, -1); //in viewDidLoad cell.transform = CGAffineTransformMakeScale(1, -1);//in tableView:cellForRowAtIndexPath: 

Créez un en-tête de tableau correspondant à la hauteur de l’écran (quelle que soit l’orientation dans laquelle vous vous trouvez) MOINS la hauteur des lignes que vous souhaitez voir visibles. S’il n’y a pas de lignes, l’en-tête correspond à la hauteur totale de la vue de table. Lorsque des lignes sont ajoutées, réduisez simultanément la hauteur de l’en-tête de la table par la hauteur de la nouvelle ligne. Cela signifie qu’il faut modifier la hauteur de l’image de la vue que vous fournissez pour l’en-tête de la table. Le but est de remplir l’espace au-dessus des lignes du tableau pour donner l’apparence que les lignes entrent par le bas. L’utilisation d’un en-tête de tableau (ou d’un en-tête de section) repousse les données de la table. Vous pouvez mettre ce que vous voulez dans la vue d’en-tête, même si vous le souhaitez.

Cela devrait avoir l’effet que vous recherchez, je pense.

Regardez l’atsortingbut tableHeaderView . Vous définissez simplement cela sur la vue que vous souhaitez afficher dans l’en-tête du tableau. Vous pouvez ensuite le manipuler selon vos besoins lorsque vous ajoutez des lignes. Je ne me souviens pas à quel point il faut être énergique pour que la vue soit réellement mise à jour dans l’interface utilisateur. Peut-être aussi simple que d’appeler setNeedsDisplay , le cas échéant.

Vous pouvez également consulter les méthodes tableView:viewForHeaderInSection: et tableView:heightForHeaderInSection: Semblable à l’utilisation d’une vue d’en-tête de table, vous souhaitez avoir une variable d’instance que vous configurez une fois, mais à laquelle vous pouvez accéder à partir de ces méthodes pour renvoyer respectivement la vue elle-même ou sa hauteur. Lorsque vous devez modifier la vue de la (première) section, vous pouvez utiliser reloadSections:withAnimation: pour forcer la mise à jour de la vue à l’écran après avoir modifié la hauteur (ou le contenu) des vues.

Tout cela a du sens? J’espere. 🙂

Swift 3.01 – Une autre solution peut être de faire pivoter et retourner la vue de la table. Fonctionne très bien pour moi et ne joue pas avec l’animation et c’est moins de travail pour les données de rechargement sur la vue de la table.

 self.tableView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(Double.pi))) self.tableView.transform = CGAffineTransform.init(translationX: -view.frame.width, y: view.frame.height) 

Je voulais juste append quelque chose à toutes ces réponses concernant l’utilisation de cette technique avec UICollectionView … Parfois, lors de l’invalidation de la mise en page, mes cellules se transformaient dans le mauvais sens, je trouvais que dans les sous-classes UICollectionViewCell fais ceci:

 - (void)applyLayoutAtsortingbutes:(UICollectionViewLayoutAtsortingbutes *)layoutAtsortingbutes { [super applyLayoutAtsortingbutes:layoutAtsortingbutes]; [self setTransform:CGAffineTransformMakeScale(1, -1)]; } 
 dataSourceArray = dataSourceArray.reversed() tableView.transform = CGAffineTransform(scaleX: 1, y: -1) cell.transform = CGAffineTransform(scaleX: 1, y: -1) func textFieldShouldReturn(_ textField: UITextField) -> Bool { if let text = textField.text { dataSourceArray.insert(text, at: 0) self.tableView.reloadData() textField.text = "" } textField.resignFirstResponder() return true } 

Eh bien, si vous chargez votre tableview avec un NSMutableArray, je vous suggère de sortinger le tableau dans l’ordre inverse. La vue de la table sera donc remplie comme vous le souhaitez.