Faire communiquer 2 ViewControllers et 1 UIPopOverController

Alf1996Alf1996 Membre
01:45 modifié dans Actualités #1
Bonjour,
Je déterre ce post dont je me suis abondamment servie pour récupérer une information d'un UIPopoverController (contenant une UITableView) pour l'afficher dans une zone de texte de mon VC principal. Après avoir tourné pas mal, j'ai enfin réussi à  faire fonctionner la chose... mais il me reste un problème que je n'arrive pas à  résoudre. Lorsque l'utilisateur à  cliqué sur un item de ma tableview, je récupère bien l'info pour l'afficher dans mon textfield, mais je n'arrive pas à  faire disparaà®tre le popovercontroller. Je pense que je ne fais pas le dismiss au bon endroit...
Quelqu'un aurait-il un une suggestion ?
Merci d'avance.  o:)

Réponses

  • muqaddarmuqaddar Administrateur
    01:45 modifié #2
    Salut,

    Pour ma part :

    - j'envoie le popoverController du controller1 vers le controller2 (avec une property assign)

    controller2ViewController.popoverController = self.popoverController;
    


    - dans le controller 2, je crée une méthode delegate  type "dismissCurrentPopover:(UIPopoverController*)pop

    @protocol Controller2ViewControllerDelegate<br />@optional<br />- (void)dismissCurrentPopover:(UIPopoverController*)aPopoverController;<br />@end<br />
    


    - méthode que j'implémente dans le controller1 :

    #pragma mark -<br />#pragma mark my popover delegate<br /><br />- (void)dismissCurrentPopover:(UIPopoverController *)aPopoverController<br />{<br />	[aPopoverController dismissPopoverAnimated:YES];	<br />}<br />
    


    - et je l'appelle donc dans le controller 2 au moment opportun, par exemple quand tu cliques sur une ligne de ton tableau :

    [delegate dismissCurentPopover:self.popoverController];
    


  • Alf1996Alf1996 Membre
    01:45 modifié #3
    Merci pour ta réponse rapide,
    Je viens d'essayer de l'appliquer, mais j'ai une ou deux questions complémentaires. Puis-je regrouper ton delegate dans mon protocole existant ? Est-ce nécessairement @optionnal ? ou est-ce que tu l'as mis optionnal parce que tu l'utilises dans plusieurs projets différents et que tu ne t'en sers pas systématiquement ?
    Concernant l'appel de la méthode déléguée, n'est pas trop tôt de l'appeler dans le didSelectRow de la tableview ?


    Voici mon code :

    .m du VC1 :
    <br /><br />-(void) didChooseContaminant:(NSString *)contam{<br />	contaminantType.text=contam;<br />	[contaminantEpaisseur becomeFirstResponder];<br />}<br /><br />#pragma mark -<br />#pragma mark my popover delegate<br /><br />- (void)dismissCurrentPopover:(UIPopoverController *)aPopoverController{<br />	[aPopoverController dismissPopoverAnimated:YES];	<br />}<br />
    


    .h du popoverVC
    <br />@class ContaminantsViewController;<br />@protocol ContaminantsDelegate &lt;NSObject&gt;<br />-(void) didChooseContaminant:(NSString *)contam;<br />@optional<br />- (void)dismissCurrentPopover:(UIPopoverController*)aPopoverController;<br />@end<br /><br /><br />@interface ContaminantsViewController : UITableViewController {<br />	id&lt;ContaminantsDelegate&gt; delegate;<br />	NSMutableArray *listOfContaminants;	<br />}<br /><br />@property(assign,nonatomic) id&lt;ContaminantsDelegate&gt; delegate;<br />@property(retain,nonatomic) NSMutableArray *listOfContaminants;<br /><br />@end<br />
    


    et .m du popoverVC
    <br />- (void)viewDidLoad {<br />	self.contentSizeForViewInPopover=CGSizeMake(190, 220);<br />	listOfContaminants=[[NSMutableArray alloc]initWithObjects:@&quot;Eau stagnante&quot;,@&quot;Slush&quot;,@&quot;Neige Mouillée&quot;,@&quot;Neige Sèche&quot;,@&quot;Neige Compacte&quot;,nil];<br />&nbsp; &nbsp; &nbsp; &nbsp; [super viewDidLoad];<br />	self.clearsSelectionOnViewWillAppear=NO;<br />}<br /><br />- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {<br />&nbsp; &nbsp; return 1;<br />}<br /><br />- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {<br />&nbsp; &nbsp; return [listOfContaminants count];<br />}<br /><br />- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; static NSString *CellIdentifier = @&quot;Cell&quot;;<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br />&nbsp; &nbsp; if (cell == nil) {<br />&nbsp; &nbsp; &nbsp; &nbsp; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />	cell.textLabel.text=[listOfContaminants objectAtIndex:indexPath.row];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; return cell;<br />}<br />- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {<br />	[self.delegate didChooseContaminant:[listOfContaminants objectAtIndex:indexPath.row]];<br />}<br />
    


    Désolée si ce sont encore des questions bêtes ! et encore merci
  • muqaddarmuqaddar Administrateur
    01:45 modifié #4
    dans 1308492028:

    Merci pour ta réponse rapide,
    Je viens d'essayer de l'appliquer, mais j'ai une ou deux questions complémentaires. Puis-je regrouper ton delegate dans mon protocole existant ?


    Oui.

    dans 1308492028:

    Est-ce nécessairement @optionnal ? ou est-ce que tu l'as mis optionnal parce que tu l'utilises dans plusieurs projets différents et que tu ne t'en sers pas systématiquement ?


    Exactement

    dans 1308492028:

    Concernant l'appel de la méthode déléguée, n'est pas trop tôt de l'appeler dans le didSelectRow de la tableview ?


    Non.

    D'ailleurs dans ton code, tu ne l'appelles pas. Appelle là  après :
    [self.delegate didChooseContaminant:[listOfContaminants objectAtIndex:indexPath.row]];

    Et sinon, oublie pas de transmettre le popover en question !


  • Alf1996Alf1996 Membre
    01:45 modifié #5
    dans 1308500623:

    Et sinon, oublie pas de transmettre le popover en question !


    Gloup!!!  :o   >:)
    Ca marche mieux comme çà  !
    J'ai néanmoins un warning, et même si çà  fonctionne, j'ai dû faire un truc qu'il n'aime pas !
    J'ai donc le warning suivant :
    Class 'UIPopoverController' does not implement the 'ContaminantsDelegate' protocol

    sur la ligne de code suivante où je déclare le popOver dans mon VC.

    <br />self.popContam.popoverController=self.popOverListe;<br />
    


    Merci d'avance...
  • muqaddarmuqaddar Administrateur
    01:45 modifié #6
    Donne moi + de code, car non, ce n'est pas normal.
    Quand tu crées ton popoverController et son controller dans VC1.

    Sinon, essayer d'appeler des controller "controller" parce que sinon c'est dur à  comprendre !

    popContam c'est bien un controller ?
  • Alf1996Alf1996 Membre
    01:45 modifié #7
    dans 1308504407:

    Donne moi + de code, car non, ce n'est pas normal.
    Quand tu crées ton popoverController et son controller dans VC1.

    Sinon, essayer d'appeler des controller "controller" parce que sinon c'est dur à  comprendre !

    popContam c'est bien un controller ?


    Oui désolée, c'est pas très clair...

    <br />-(IBAction) showContaminants{<br />	if (self.popContam==nil) {<br />		self.popContam = [[[ContaminantsViewController alloc] init] autorelease];<br />		self.popContam.delegate=self;<br />		self.popOverListe = [[[UIPopoverController alloc] initWithContentViewController:popContam] autorelease];<br />		self.popContam.popoverController=self.popOverListe;<br />	}<br />	CGRect popRect=[self.view convertRect:[contaminantType frame] fromView:[contaminantType superview]];<br />	popRect.size.width=MIN(popRect.size.width,190);<br />	[self.popOverListe presentPopoverFromRect:popRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];<br />}<br />
    

  • muqaddarmuqaddar Administrateur
    01:45 modifié #8
    Il me semble que ton code est bon...

    Tu l'as déclaré comment ton popoverController dans popContam.h ?
  • Alf1996Alf1996 Membre
    01:45 modifié #9
    Voila le .h du ContaminantsViewController :
    <br />//<br /><br />@class ContaminantsViewController;<br />@protocol ContaminantsDelegate &lt;NSObject&gt;<br />-(void) didChooseContaminant:(NSString *)contam;<br />-(void) dismissCurrentPopover:(UIPopoverController*)aPopoverController;<br />@end<br /><br /><br />@interface ContaminantsViewController : UITableViewController {<br />	id&lt;ContaminantsDelegate&gt; delegate;<br />	id&lt;ContaminantsDelegate&gt; popoverController;<br />	NSMutableArray *listOfContaminants;	<br />}<br /><br />@property(assign,nonatomic) id&lt;ContaminantsDelegate&gt; delegate;<br />@property(assign,nonatomic) id&lt;ContaminantsDelegate&gt; popoverController;<br />@property(retain,nonatomic) NSMutableArray *listOfContaminants;<br /><br />@end<br />
    


    Ce qui est bizarre, c'est que je ne vois le warning que lorsque je visualise le code du view controller, alors que dans la fenêtre "build results", il n'y a rien ; c'est difficile à  expliquer, je joins deux copies d'écran.
    Merci



  • muqaddarmuqaddar Administrateur
    01:45 modifié #10
    Ceci ne sert à  rien:

    id&lt;ContaminantsDelegate&gt; popoverController;
    


    Il faut juste mettre une ivar:

    UIPopoverController *popoverController;
    


    Et sa property:

    @property (nonatomic, assign) UIPopoverController *popoverController;
    


    Car il n'y a besoin que de ce delegate:

    id&lt;ContaminantsDelegate&gt; delegate;
    
  • AliGatorAliGator Membre, Modérateur
    01:45 modifié #11
    Faudrait pas splitter le sujet alex?
  • Alf1996Alf1996 Membre
    01:45 modifié #12
    Merci Muqaddar,
    C'était bien çà  ! Et maintenant tout marche nickel 

    @Ali : c'est vrai, je me suis posé la question... Je n'étais plus vraiment dans le bon topic. Je me suis raccrochée à  ce post car j'utilisais ton tutoriel sur les protocol à  l'origine, mais j'aurais peut-être dû créer un nouveau sujet dans la rubrique "utilisation des class cocoa"...

    Quoi qu'il en soit, mon problème est maintenant résolu. Merci pour tout    <3
Connectez-vous ou Inscrivez-vous pour répondre.