web-dev-qa-db-fra.com

Recharger UITableView lors de la navigation de retour?

J'ai un niveau supérieur UIViewController qui contient un UITableView. Le niveau supérieur UIViewController instancie un NavigationController et pousse un autre UIViewController sur le NavigationController. C'EST À DIRE. nous poussons dans une nouvelle, deuxième vue. Cette deuxième vue a le bouton "Retour" habituel dans le coin supérieur gauche pour vous permettre de revenir à la vue de niveau supérieur.

Est-il possible, lorsque vous revenez à la vue de niveau supérieur à partir de la deuxième vue, de redessiner le UITableView dans la vue de niveau supérieur, en utilisant les données générées dans la deuxième vue, en appelant cellForRowAtIndexPath dans le haut niveau et si oui, comment faire?

54
James Testa

Tout ce que vous devez faire est ceci (dans votre UIViewController qui a un UITableView). Vous n'avez pas à vous soucier de ce qui se passe au niveau de la cellule à ce stade.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView reloadData]; // to reload selected cell
}

Ajoutez simplement le code ci-dessus à votre contrôleur, et vous verrez que la bonne chose se produit lorsque vous revenez de votre deuxième vue. L'appel à reloadData indique à la vue de table qu'il doit actualiser ses cellules à partir de votre modèle, et tout le reste suit bien.

110
Zoran Simic

Si vous souhaitez uniquement recharger la cellule sélectionnée, remplacez viewWillAppear: dans votre sous-classe personnalisée de UITableViewController comme ceci:

- (void)viewWillAppear:(BOOL)animated
{
    NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow];
    [super viewWillAppear:animated]; // clears selection
    if (selectedRowIndexPath) {
        [self.tableView reloadRowsAtIndexPaths:@[selectedRowIndexPath] withRowAnimation:UITableViewRowAnimationNone];
    }
}

REMARQUE: en supposant que vous avez laissé clearsSelectionOnViewWillAppear défini sur YES (par défaut), vous devez obtenir le chemin d'index de la ligne sélectionnée avant d'appeler super, ce qui efface la sélection.

De plus, la solution de @ZoranSimic pour appeler simplement [self.tablView reloadData] est acceptable car il est moins de code et toujours efficace.

Enfin, la meilleure façon de synchroniser les cellules de votre vue de tableau avec les objets du modèle qu'elles représentent est de faire comme NSFetchedResultsController et d'utiliser l'observation des valeurs-clés (KVO) et/ou NSNotification pour informer votre contrôleur de vue de table lorsque les objets du modèle ont changé afin de pouvoir recharger les cellules correspondantes. Le contrôleur de vue de table peut commencer à observer les modifications apportées à ses objets de modèle dans viewDidLoad et terminer l'observation dans dealloc (et partout où vous déchargez manuellement self.view ).

12
ma11hew28

En plus du réponse de Zoran Simic ici le code Swift:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
}
7
Michael Dorner

Vous pouvez implémenter les méthodes de UINavigationControllerDelegate et créer la logique de l'actualisation lors du popping des contrôleurs de vue.

Une autre façon de procéder consiste à implémenter sur votre contrôleur de vue de table une logique sur viewWillAppear, à actualiser en fonction des données du contrôleur de vue surgie.

Si vous devez envoyer des données du deuxième contrôleur de vue au premier contrôleur de vue, n'oubliez pas que votre deuxième contrôleur de vue "ne" connaît pas l'existence du contrôleur de vue précédent. Il doit être transparent pour cela. Vous devez implémenter un protocole pour que le second contrôleur de vue envoie des données au premier contrôleur de vue. Ce serait une troisième option à ce problème, car votre premier contrôleur de vue serait le délégué et le deuxième contrôleur de vue enverrait des informations au délégué, vous pourriez préparer votre vue de table (premier contrôleur de vue) à recharger, en fonction de la données reçues.

5
vfn

viewWillAppear est appelé chaque fois que la vue apparaît, y compris la première fois. Voici ma solution pour recharger la vue uniquement lorsque vous revenez en arrière

Je crée une variable dans .h file de mon ViewController pour avoir vérifié que c'est la première fois que j'y vais ViewController ou quand je reviens

@property (nonatomic) BOOL isViewExist;

Après cela dans viewWillAppear

-(void)viewWillAppear:(BOOL)animated{
    if(!self.isViewExist){
        self.isViewExist = YES; // check it is the first time you go to this ViewController -> don't reload anything
    }else{
        [self.tableView reloadData]; // to reload the tableview data
        // or your can refresh anything in your ViewController as you want
    }
}

J'espère que cette aide

3
Phan Van Linh

Peut-être que ça peut aider maintenant.

Pour Swift 2 +

Dans votre méthode viewDidAppear:

Si vous souhaitez recharger toutes les tables:

tableView.reloadData()

Si vous souhaitez recharger uniquement la cellule sélectionnée.

let index = tableView.indexPathForSelectedRow
if (index != nil){
  self.tableView.reloadRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Automatic)
}
1
Dasoga

Mis à jour pour Swift 3

let index = tableView.indexPathForSelectedRow
    if (index != nil){
        self.tableView.reloadRows(at: [index!], with: UITableViewRowAnimation.automatic)
    }
0
Robin Thomson