web-dev-qa-db-fra.com

Comment obtenir une UITableview pour aller en haut de la page lors du rechargement?

J'essaie d'obtenir une UITableview pour aller au haut de la page lorsque je recharge les données de la table lorsque j'appelle le suivant

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {

// A bunch of code …

[TableView reloadData];
}

Dans le même ordre d'idées, j'aimerais également pouvoir accéder à une section spécifique lorsque je recharge les données du tableau.

J'ai essayé de placer les éléments suivants, qui semblent applicables uniquement à la ligne, avant et après le rechargement, mais rien ne se passe:

[TableView scrollToRowAtIndexPath:0 atScrollPosition:UITableViewScrollPositionTop  animated:YES];
27
AppsToKnow

Voici une autre façon de le faire:

Objectif c

[tableView setContentOffset:CGPointZero animated:YES];

Swift 3

tableView.setContentOffset(.zero, animated: true)

Probablement le moyen le plus simple et le plus simple de le faire.

59
Erik B

Après avoir lu toutes les réponses ici et ailleurs, j'ai finalement trouvé une solution fiable qui ne montre pas le défilement après le chargement des données. Ma réponse est basée sur ce post et mon observation selon laquelle vous avez besoin d’un décalage négatif si vous utilisez des encarts de contenu:

func reloadAndScrollToTop() {
    tableView.reloadData()
    tableView.layoutIfNeeded()
    tableView.contentOffset = CGPoint(x: 0, y: -tableView.contentInset.top)
}
21
phatmann

Pour faire défiler une section spécifique, vous devez spécifier le chemin d'accès à son index:

NSIndexPath *topPath = [NSIndexPath indexPathForRow:0 inSection:0];
[TableView scrollToRowAtIndexPath:topPath
                 atScrollPosition:UITableViewScrollPositionTop
                         animated:YES];

Si vous n'êtes pas sûr du nombre de lignes dans votre tableView. Utilisez le suivant:

NSIndexPath *topPath = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
[TableView scrollToRowAtIndexPath:topPath
                 atScrollPosition:UITableViewScrollPositionTop
                         animated:YES];
18
ragamufin

Cela fonctionne pour moi.

tableView.scrollToRow(at: IndexPath.init(row: 0, section: 0), at: .top, animated: true)
12
sc13

SANS ANIMATION

Je suis sur iOS11, j'utilise un style de vue de table simple avec des en-têtes collants et la seule façon dont cela fonctionnait correctement pour que la vue de table soit vraiment au-dessus après un rechargement sans aucun comportement étrange/comportement d'animation était d'utiliser ces méthodes dans cet ordre. où TOUTES sont nécessaires:

[self.tableView setContentOffset:CGPointZero animated:NO];
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
[self.tableView setContentOffset:CGPointZero animated:NO];

Je suis sérieux que tout cela est nécessaire, même s'il semble que la première ligne n'est pas pertinente du tout. Oh oui, aussi très important , NE PAS utiliser ceci:

self.tableView.contentOffset = CGPointZero;

On pourrait penser que c'est la même chose que "setContentOffset animated: FALSE" mais apparemment ce n'est pas le cas! Apple traite cette méthode différemment et, dans mon cas, cela ne fonctionnait que si vous utilisiez la méthode complète avec animation: FALSE.

AVEC ANIMATION

Je voulais aussi essayer cela avec une belle animation de défilement vers le haut. Là, les méthodes de compensation de contenu semblaient toujours provoquer des comportements d’animation étranges. La seule façon pour moi de faire fonctionner cette animation avec une animation Nice après quelques essais et erreurs était la suivante:

[self.tableView reloadData];
[self.tableView layoutIfNeeded];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:TRUE];

Attention, assurez-vous d'avoir au moins 1 ligne avant d'exécuter la dernière ligne de code pour éviter les plantages :) 

J'espère que cela aidera quelqu'un un jour!

5
Bob de Graaf

UITableView est une sous-classe de UIScrollView, vous pouvez donc également utiliser:

[mainTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
4
D.Enchev

Dans Swift 3.1 

DispatchQueue.main.async(execute: {

        self.TableView.reloadData()
        self.TableView.contentOffset = .zero

    })
1
Mahipalsinh

Vous devez faire défiler UITableView à la première ligne de votre vue tableau à l'aide de cette ligne de code:

self.yourTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
1
Rahul Panzade

Si vous faites défiler avant de recharger et que le nombre de lignes diminue, vous pouvez avoir un comportement d'animation étrange. Pour vous assurer que le défilement se produit après le rechargement, utilisez une méthode comme celle-ci:

- (void)reloadTableViewAndScrollToTop:(BOOL)scrollToTop {
    [self.tableView reloadData];
    if (scrollToTop) {
        [self.tableView setContentOffset:CGPointZero animated:YES];
    }
}
0
skensell

Pour ceux qui trouvent encore une solution à cela, vous pouvez utiliser l'extension suivante de UITableView.

Y compris une vérification où la première section a des rangées ou non. Il va jusqu'à ce que la section avec la (les) rangée (s) vienne et ensuite défile jusqu'à celle-là.

extension UITableView {

    func scrollToFirst() {

        self.reloadData() // if you don't want to reload data, remove this one.
        for i in 0..<self.numberOfSections {

            if self.numberOfRows(inSection: i) != 0 {

                self.scrollToRow(at: IndexPath(row: 0, section: i), at: .top, animated: true) 
                break 
            }
        }
    }
}

J'espère que cela vous a aidé.

0
viral

Certaines des réponses que j’ai trouvées à cette question me laissaient un peu perplexe à cause d’explications incomplètes. D'après ce que j'ai recueilli, il y a deux itinéraires pour accomplir ce que l'OP a demandé. Ils sont les suivants:

1) Si l'animation n'est pas une exigence, nous vous suggérons de rétablir la position de défilement avant le chargement des données à l'aide de l'une des méthodes de décalage. La raison pour laquelle vous devez exécuter offset avant reloadData est que reloadData s'exécute de manière asynchrone. Si vous exécutez offset après rechargement, votre position de défilement sera probablement quelques lignes plus bas.

tableView.setContentOffset(.zero, animated: false)
tableView.reloadData()

2) Si l'animation est une exigence, positionnez votre défilement sur la rangée supérieure après avoir exécuté reloadData à l'aide de scrollToRow. La raison pour laquelle scrollToRow fonctionne ici est qu'il vous positionne en haut de la table, par rapport à la méthode de décalage qui vous positionne par rapport aux données déjà chargées.

tableView.reloadData()
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
0
Braden Holt