web-dev-qa-db-fra.com

Mémoriser la position de défilement sur UITableView

J'ai un problème avec mon application iOS en xcode. J'ai un UITableView qui charge quelques centaines de cellules. Lorsque je descends dans une cellule spécifique et que je fais un zoom avant sur detailedviewcontrollers et que je retourne à nouveau, la table de vue principale est retournée jusqu'au sommet. J'ai examiné les 2 questions suivantes qui sont similaires.

Comment puis-je obtenir la position de défilement de UITableView afin de pouvoir l'enregistrer?

Définition de la position de défilement dans UITableView

Je n'arrive toujours pas à les faire fonctionner. Je ne suis pas le codeur le plus expérimenté, alors je suis vraiment en difficulté avec ça.

Je sais que des choses comme viewWillDisappear et viewDidAppear doivent être changées, mais je ne peux vraiment pas aller plus loin que cela.

Sur cette table, j'ai une fonctionnalité reloadData, il est donc possible d'extraire les dernières données du serveur et une barre de recherche qui fonctionne.

De toute façon, un coup de main serait bien. Merci,

Luke

29
mylogon

Trié!

En m'inspirant un peu de Desdenova, au travail, j'ai bien réfléchi et compris ce que cela pouvait être. En me rappelant que j'avais une barre de recherche, j'avais implémenté le code suivant il y a quelques mois pour le masquer:

[self.tableView setContentOffset:CGPointMake(0,-20) animated:NO];

Par naïveté, je mets cela dans viewDidAppear plutôt que viewDidLoad. Évidemment, cela masquait la barre de recherche, mais comme il était dans la mauvaise commande void, il le faisait chaque fois que masterDetailView revenait au sommet de la pile. Ainsi, après avoir déplacé le code ci-dessus vers viewDidLoad, il le cache toujours, mais une seule fois.

Je le répète simplement comme cela pour d’autres débutants, comme moi, qui risquent de rencontrer le même problème et de sauver leur santé mentale!

Merci à vous tous pour vos idées qui m'ont aidé.

+1 à vous tous!

11
mylogon

Voir ici que vous devez d’abord enregistrer la position de défilement de tableView c’est-à-dire contentOffset de tableView, puis de la réutiliser lorsque vous revenez à tableView.

1) Quand et où vous allez le sauvegarder:

When : Au moment où vous explorez jusqu'à detailViewController, enregistrez la contentOffset de tableView

Comment : float verticalContentOffset = tableView.contentOffset.y;

2) Comment allez-vous remettre tableView à la même position défilée:

[tableView setContentOffset:CGPointMake(0, verticalContentOffset)];

J'espère que ceci vous aidera.

66
Prashant Nikam

Si quelqu'un se le demande, j'ai essayé la solution de Prashant N et cela a fonctionné. Cependant, reloadData ne réinitialise plus réellement la position de défilement à présent, je n'ai donc rien d'autre à faire que reloadData.

1
Enrico Susatyo

Pour une raison quelconque, cela fonctionnait à mi-chemin pour moi (parfois, le poste serait approximatif) J'ai finalement utilisé la solution suivante à priori moins propre

NSIndexPath *firstVisibleIndexPath = [[self.tableView indexPathsForVisibleRows] objectAtIndex:0];
[self.tableView scrollToRowAtIndexPath:self.firstVisibleIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
self.firstVisibleIndexPath = firstVisibleIndexPath;

qui a fonctionné mieux.

1
vib

Ma décision pour une collection:

CGFloat oldCollectionViewHeight = self.messageCollectionView.contentSize.height;

[self.messageCollectionView reloadData];
[self.messageCollectionView layoutIfNeeded];

CGFloat newCollectionViewHeight = self.messageCollectionView.contentSize.height;

if (oldCollectionViewHeight) {
    self.messageCollectionView.contentOffset = CGPointMake(0, newCollectionViewHeight - oldCollectionViewHeight);
}

Pour la table, le principe est le même.

1
Dmitry Malysh

Ma solution à ce problème a consisté à faire défiler le tableau jusqu'à l'indexrow du dernier élément.

private func scrollToItem(item:Int, section:Int bottom:Bool = true, animated:Bool = false) {
    let indexPath = NSIndexPath(forRow: item:Int-1, inSection: section)
    var position = UITableViewScrollPosition.Bottom
    if (!bottom) { position = UITableViewScrollPosition.Top }
    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: position, animated: animated)
}
1
Guilherme Carvalho

Comme mentionné dans d'autres commentaires, le comportement par défaut ne fait pas défiler vers le haut la navigation arrière dans un contrôleur UINavigationController.

Une autre cause peut être que vous définissez une cellule près du haut de la table en tant que premier répondant dans viewWillAppear, par exemple. un champ de recherche ou un champ d'édition situé en haut de votre tableau. UITableViewController fera défiler automatiquement le premier répondant, qui est Nice. Tant que c'est ce que vous essayez de faire. :) Veillez à ne pas définir le premier répondant dans viewWillAppear sauf si c'est ce que vous voulez. À la vôtre, AZ

0
andyzei

Vous n’avez rien à faire, même si vous êtes dans le même contrôleur de vue, votre position sera la même. Je crains que quelque part dans votre contrôleur de vue ne s'appelle reloadData. Recherchez une méthode appelant scrollToRowAtIndexPath. 

0
aph340