8 votes

Comment faire apparaître un viewController et ensuite pousser un viewController par délégation ?

J'ai un UITableViewController qui, lorsqu'on appuie sur une cellule, doit s'ouvrir, puis le contrôleur vers lequel il s'ouvre doit pousser un autre contrôleur de vue sur la pile.

J'invoque cette méthode parce que le popped-to viewController est le délégué du tableViewController.

Je suis actuellement en train d'invoquer cette méthode avec un délai, parce que sinon, tout s'embrouille en attendant la fin de l'animation. Cette façon de faire me semble un peu compliquée et j'ai l'impression qu'elle échouerait si l'appareil de quelqu'un n'ouvrait pas la vue dans le temps d'attente que je lui ai donné.

Voici une partie du code :

//**** code in my tableViewController ***//

[self.navigationController popViewControllerAnimated:YES];
[self.delegate cellPressedInTableViewControllerWithCalculationsModel:(id)anArgmentMyDelegateMethodTakes];

// **** Code in the viewController being popped to ****//
//CalculationsViewController is a subclass of UIViewController
CalculationsViewController *calcViewController = [[CalculationsViewController alloc] init];

//some customization code would go her

[self.navigationController performSelector:@selector(pushViewController:animated:) withObject:calcViewController afterDelay:0.75];
//this seems like the arbitrary part, the 0.75 second delay.

[calcViewController release];

Il semble qu'il devrait y avoir un meilleur moyen de faire passer une délégation qui s'exécutera après la fin de l'animation. Le temps d'attente me semble pouvoir causer des problèmes inattendus.

J'ai également essayé d'utiliser :

 performSelectorOnMainThread:withObject:waitUntilDone

Mais le code s'exécute immédiatement et la hiérarchie de la vue est foutue.

Je me suis également penché sur cette question : Question de délégation et cela m'a permis d'aller jusqu'ici, mais je suis curieux de savoir s'il existe une meilleure façon d'effectuer une telle tâche, Merci.

edit : J'ai également essayé d'envelopper la méthode dans une instance de NSInvocation, et je n'ai pas réussi à coordonner l'appel de la méthode jusqu'à la fin de l'animation sans régler arbitrairement le délai.

38voto

Jason Moore Points 2415

La façon la plus propre de faire plus qu'un simple push ou pop d'un contrôleur de vue est de définir le paramètre UINavigationController dans le tableau des contrôleurs de vue.

Par exemple, pour faire sauter puis pousser un contrôleur de vue :

MyTableViewController *vc = [[MyTableViewController alloc] init];

NSMutableArray *controllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[controllers removeLastObject];
[controllers addObject:vc];

[self.navigationController setViewControllers:controllers animated:YES];

5voto

Darshan Prajapati Points 628

Vous devez utiliser un drapeau pour surmonter cette situation. Vous définissez ce drapeau dans la méthode viewWillDisappear du contrôleur de vue en cours d'extraction. Lorsque ce drapeau est activé, vous pouvez pousser un autre contrôleur de vue sur la pile. J'espère que c'est clair.

3voto

Zhang Points 3585

Et si, lorsque vous congédiez votre UIViewController contenant la table, vous envoyiez une NSNotifcation dans votre méthode viewDidDisappear comme suit :

- (void)viewDidDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"loadOtherVC" object:nil];
}

Et dans votre contrôleur de vue parent qui va pousser un nouveau contrôleur de vue, vous ajoutez un observateur pour cette notification comme ceci :

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(LoadOtherVC:) name:@"loadOtherVC" object:nil];

Vous devriez avoir une méthode qui correspond au sélecteur.

- (void) LoadOtherVC:(NSNotification *) notification
{
    // load your other view controller you want here
}

0voto

Nathanial Woolls Points 4106

Ne le lancez pas depuis le contrôleur de niveau supérieur. Appelez la méthode du délégué qui fera sortir la vue du contrôleur de navigation, puis en ajoutera une nouvelle.

0voto

user3871797 Points 21

J'ai aimé la solution d'Alexandre mais si j'étais un délégué, je ne voudrais pas utiliser la notification. Donc, dans ce cas, nous pouvons simplement utiliser le délégué dans la section viewDidDisappear método.

Ainsi, dans le didSelectRowAtIndexPath vous pouvez ouvrir le contrôleur.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
     [self.navigationController popViewControllerAnimated:YES];
}

et dans le même contrôleur de vue, le ViewController que vous êtes en train de vidanger, appelez la méthode de délégué dans le fichier viewDidDisappear une méthode comme

-(void)viewDidDisappear:(BOOL)animated{
   [self.delegate cellPressedInTableViewControllerWithCalculationsModel:(id)anArgmentMyDelegateMethodTakes];
}

Ensuite, dans le contrôleur qui est poussé peut mettre en œuvre la méthode du délégué et à l'intérieur de cette méthode du délégué, vous pouvez faire ce que vous voulez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X