web-dev-qa-db-fra.com

UITableView lignes d'ancrage vers le bas

J'ai un UITableView qui doit introduire un nouveau contenu à partir du bas. Voici comment se présente une vue sous forme de tableau lorsque la vue est pleine et que vous ajoutez de nouvelles lignes avec animation.

Je commençais en modifiant le contentInset au fur et à mesure que les lignes étaient introduites, mais ensuite, les choses se passaient mal et l'animation des entrées était complètement fausse ... Mon problème avec cette approche est aggravé par le fait que les utilisateurs peuvent supprimer des lignes et la ligne le contenu est mis à jour, ce qui entraîne leur redimensionnement (chaque ligne a sa propre hauteur qui change).

Des recommandations sur la manière de faire en sorte qu'une ligne UITableView apparaisse toujours au bas de l'espace d'affichage de UITableView?

38
ima747

J'ai une solution qui fonctionne parfaitement pour moi, mais elle entraîne une double réflexion, donc ce n'est pas aussi simple en théorie que dans la pratique ... un peu ...

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

tableView.transform = CGAffineTransformMakeRotation(-M_PI);

Étape 2, faites pivoter votre cellule brute de 180 degrés 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 objets à l'emplacement 0 au lieu d'utiliser AddObject ...

Maintenant, la partie difficile est de se rappeler que la gauche est à droite et que la droite est laissée uniquement 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.

En fonction de votre magasin de données, vous devrez peut-être gérer cela dans l'ordre inverse également ...

Remarque: faites pivoter les cellules OPPOSITION au tableau, sinon l'innacuracy en virgule flottante pourrait provoquer une transformation parfaite et vous obtiendrez des analyses de certains graphismes de temps en temps lorsque vous faites défiler ... mineur mais ennuyeux.

70
ima747

La méthode acceptée introduit des problèmes pour mon application - la barre de défilement est du mauvais côté et modifie 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); 
39
Nick H247

Approche similaire à ima747, mais avec une rotation de 180 degrés, l'indicateur de défilement se place également du côté opposé. Au lieu de cela, j'ai retourné la vue du tableau et ses cellules verticalement.

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

cell.transform = CGAffineTransformMakeScale(1, -1);//in tableView:cellForRowAtIndexPath:
16
Jeffrey Sun

Swift 3.01 - Une autre solution peut être, faire pivoter et retourner la vue du tableau. Fonctionne très bien pour moi et ne plaisante pas avec l’animation et nécessite moins de travail pour le rechargement des données dans la vue tableau.

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

Créez un en-tête de tableau qui correspond à la hauteur de l'écran (quelle que soit l'orientation dans laquelle vous vous trouvez) MOINS la hauteur des lignes que vous souhaitez afficher. S'il n'y a pas de lignes, l'en-tête correspond à la hauteur totale de la vue tabulaire. Au fur et à mesure que les lignes sont ajoutées, réduisez simultanément la hauteur de l'en-tête de table par la hauteur de la nouvelle ligne. Cela signifie que vous modifiez la hauteur du cadre de la vue que vous fournissez pour l'en-tête du tableau. 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 table (ou en-tête de section) abaisse les données de la table. Vous pouvez mettre ce que vous voulez dans la vue en-tête, même le laisser vide et transparent si vous le souhaitez.

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

Regardez l'attribut tableHeaderView. Vous définissez simplement ceci à la vue que vous voulez afficher dans l'en-tête du tableau. Vous pouvez ensuite le manipuler au besoin lorsque vous ajoutez des lignes. Je ne me souviens pas à quel point vous devez être puissant pour que la vue soit réellement mise à jour dans l'interface utilisateur. Pourrait être aussi simple que d'appeler setNeedsDisplay, le cas échéant.

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

Tout ça a du sens? J'espere. :-)

2
Mark Granoff
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
}
0
Daniel Long

Je voulais juste ajouter quelque chose à toutes ces réponses concernant l'utilisation de cette technique avec UICollectionView ... Parfois, lorsque j'invalidais la mise en page, mes cellules étaient transformées de nouveau, j'ai constaté que dans les sous-classes UICollectionViewCell et UICollectionReusableView que je devais faire ceci: 

- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    [super applyLayoutAttributes:layoutAttributes];
    [self setTransform:CGAffineTransformMakeScale(1, -1)];
}
0
lramirez135