2010-09-19 3 views
53

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.Recharger UITableView lors de la navigation arrière?

Est-il possible, lors de la navigation de retour à la vue de haut niveau de la deuxième vue, de redessiner la UITableView dans la vue de haut niveau, en utilisant les données générées dans la deuxième vue, en appelant cellForRowAtIndexPath au niveau supérieur et si oui, Comment est-que quelqu'un peut faire ça?

Répondre

105

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 
} 

il suffit d'ajouter le code ci-dessus pour votre contrôleur, et vous verrez que la bonne chose arrive quand vous revenez de votre second point de 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.

+1

i utilisé cette méthode, mais a dû déplacer le code de mon didViewLoad à viewWillAppear comme ils lorsque les deux tir de la charge initiale. Pour moi c'était un plus gros problème parce que j'ai besoin de télécharger les nouveaux détails d'un service web – PowerMan2015

5

Vous pouvez implémenter les méthodes de UINavigationControllerDelegate et créer la logique pour le rafraîchissement lors de l'ouverture 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 éclaté.

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. Cela devrait être transparent pour cela. Vous devez implémenter un certain 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, puisque 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 (contrôleur de première vue) pour recharger, basé sur le données reçues.

10

Si vous voulez seulement recharger la cellule qui a été sélectionné, passer outre 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]; 
    } 
} 

NOTE: En supposant que vous avez quitté clearsSelectionOnViewWillAppear ensemble à YES (valeur 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.

En outre, le solution of @ZoranSimic pour appeler simplement [self.tablView reloadData] est acceptable car c'est moins de code et toujours efficace. Enfin, la meilleure façon de synchroniser les cellules de votre vue de table avec les objets de modèle qu'elles représentent est de faire NSFetchedResultsController et d'utiliser l'observation par clé-valeur (KVO) et/ou NSNotification pour informer votre contrôleur de vue de table lorsque le modèle les objets ont changé afin de recharger les cellules correspondantes. Le contrôleur de vue de table peut commencer à observer les modifications apportées à ses objets de modèle au viewDidLoad et à l'observation de fin dans dealloc (et partout où vous manually unload self.view).

6

En plus du answer of Zoran Simic ici le code Swift:

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) 
    tableView.reloadData() 
} 
+0

Faites attention à ne pas obtenir les données de 'viewDidLoad()' quand vous voulez recharger les données de 'viewWillAppear()'. –

1

peut-être aider maintenant.

Pour Swift 2+

Dans votre méthode viewDidAppear:

Si vous voulez recharger toutes les tables:

tableView.reloadData() 

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

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

viewWillAppear est appelé à chaque fois que la vue semble inclure la première fois. Voici ma solution pour recharger la vue que lorsque vous naviguez en arrière

Je crée une variable .h file de mon ViewController pour vérifier qu'il est la première fois que je vais à ce ViewController ou lorsque je navigue en arrière

@property (nonatomic) BOOL isViewExist; 

Après que 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 
    } 
} 

Hope this aide

-1

Mise à jour pour Swift 3

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

_in - override func viewDidLoad() ou ??? _ - commente au nom de l'utilisateur qui ne peut pas commenter – Tushar

Questions connexes