Aller au contenu

Photo

[Résolu] Problème delegate


  • Please log in to reply
22 replies to this topic

#1 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 18 septembre 2012 - 16:02

Bonjour,

j'ai défini le protocole suivant dans la classe CreationTacheViewController :

[c]@interface CreationTacheViewController : UIViewController <UITextViewDelegate>

@property (nonatomic, assign) id <CreateTacheDelegate> delegate;
...
@end

@protocol CreateTacheDelegate <NSObject>
- (void)createTacheController:(CreationTacheViewController *)controller didCreateTache:(Tache *)tache;
@end[/c]

et j'utilise ce protocole dans la classe TacheViewController où je définis la méthode comme suis :

[c]- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"creationTache"])
{
_creationTacheViewController = [[CreationTacheViewController alloc] init];
_creationTacheViewController.delegate = self;
}
}

- (void)createTacheController:(CreationTacheViewController *)controller didCreateTache:(Tache *)tache
{
tache.projet = _projet;
[_projet.managedObjectContext save:nil];
[_tacheArray addObject:tache];
[self.tableView reloadData];
}[/c]

Le problème c'est qu'une fois dans l'exécution du code de la classe CreationTacheViewController l'objet delegate est a nil ce qui fait que la méthode [c]createTacheController didCreateTache[/c] n'est pas appelé, je voudrais donc savoir comment faire pour que l'objet delegate ne soit pas null.

merci d'avance

Ce message a été modifié par BenArko - 19 novembre 2012 - 18:38.


#2 iDevelopper

iDevelopper

    iPuP maître

  • Moderators
  • 1278 Messages :
  • LocationSaint-Aygulf

Posté 18 septembre 2012 - 16:56

Dans le .h de TacheViewController, as tu adopter le protocole ?

@interface TacheViewController : UIUIViewController <CreateTacheDelegate>
La tolérance désigne la capacité à accepter ce que l'on désapprouve. En construction par exemple, on dit qu'on peut tolérer une certaine marge d'erreur.

#3 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 18 septembre 2012 - 18:06

Oui j'ai bien adopté le protocole

#4 iDevelopper

iDevelopper

    iPuP maître

  • Moderators
  • 1278 Messages :
  • LocationSaint-Aygulf

Posté 19 septembre 2012 - 06:10

Remplace assign par retain dans @property
La tolérance désigne la capacité à accepter ce que l'on désapprouve. En construction par exemple, on dit qu'on peut tolérer une certaine marge d'erreur.

#5 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 19 septembre 2012 - 14:01

Ca ne change rien.

#6 R40ul

R40ul

    iPuP apprenti

  • Members
  • 96 Messages :

Posté 19 septembre 2012 - 14:18

Essaye de créer une nouvelle fonction init pour ton CreationTacheViewController qui prendrait le delegate en paramètre, et ensuite appelle :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

    if ([[segue identifier] isEqualToString:@"creationTache"])

    {

        _creationTacheViewController = [[CreationTacheViewController alloc] initWithDelegate:self];

    }

}


#7 iDevelopper

iDevelopper

    iPuP maître

  • Moderators
  • 1278 Messages :
  • LocationSaint-Aygulf

Posté 19 septembre 2012 - 14:33

Je ne comprends pas. Peux tu donner plus de code ?
La tolérance désigne la capacité à accepter ce que l'on désapprouve. En construction par exemple, on dit qu'on peut tolérer une certaine marge d'erreur.

#8 R40ul

R40ul

    iPuP apprenti

  • Members
  • 96 Messages :

Posté 19 septembre 2012 - 16:48

Dans ta classe CreationTacheViewController, tu déclares une fonction comme ça :
- (id)initWithDelegate:(id)p_delegate
{
  self = [super init];
  if( self )
  {
    self.delegate = p_delegate;
  }
  return self;
}
Ça ne change pas grand chose par rapport à ce que tu faisais précedement, mais ça te permet de mettre des breakpoint dans ton init pour être sûr que ton delegate prend bien la valeur.

Sinon, est ce que tu es sûr que ton premier TacheViewController n'est pas désalloué quand tu passes dans ta seconde vue (CreationTacheViewController)?

#9 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 19 septembre 2012 - 17:02

@R40ul j'ai test ce que tu m'a dit et le delegate prend bien la valeur mais le résultat est le même une fois dans le deuxième controller, le delegate est toujours null. Sinon comment savoir que mon premier TacheViewController n'est pas désalloué ?

@iDevelopper que veut-tu comme code ?

#10 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 30 septembre 2012 - 20:47

le problème vient peut être du fait que dans mon storyboard ma segue "pointe" un navigation controller et non directement sur la vue qui m'intéresse ?

sinon voici le code de ma classe "TacheViewController.h" :

#import <UIKit/UIKit.h>
#import "CreationTacheViewController.h"
#import "Projet.h"
#import "Tache.h"


@interface TacheViewController : UITableViewController <CreateTacheDelegate>

@property (strong, nonatomic) Projet *projet;
@property (strong, nonatomic) CreationTacheViewController *creationTacheViewController;
@property (strong, nonatomic) NSMutableArray *tacheArray;

@end
[---]

le code de la classe "TacheViewController.m" :

#import "TacheViewController.h"
#import "CreationTacheViewController.h"


@interface TacheViewController ()

@end

@implementation TacheViewController
@synthesize projet = _projet;
@synthesize tacheArray = _tacheArray;
@synthesize creationTacheViewController = _creationTacheViewController;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
        
    //mettre le titre
    self.title = _projet.titre;
    
    //initialisation du tableau à partir des taches du projet
    _tacheArray = [[NSMutableArray alloc] initWithArray:[_projet.tache allObjects]];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown && interfaceOrientation != UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _tacheArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TacheCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (cell ==nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    
    Tache *laTache = (Tache *)[_tacheArray objectAtIndex:indexPath.row];
    cell.textLabel.text = laTache.titre;
    
    return cell;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"creationTache"])
    {
        _creationTacheViewController = [[CreationTacheViewController alloc] initWithDelegate:self];
//        _creationTacheViewController.delegate = self;
    }
}

/*- (void)viewWillAppear:(BOOL)animated
{
    [self.tableView reloadData];
}*/

- (void)createTacheController:(CreationTacheViewController *)controller didCreateTache:(Tache *)tache
{
    tache.projet = _projet;
    
    [_projet.managedObjectContext save:nil];
    
    [_tacheArray addObject:tache];
    
    [self.tableView reloadData];
}

@end
[---]

le code de la classe "CreationTacheViewController.h" :

#import <UIKit/UIKit.h>
#import "Tache.h"
#import "Projet.h"

@class Tache;
@class CreationTacheViewController;

@protocol CreateTacheDelegate <NSObject>

- (void)createTacheController:(CreationTacheViewController *)controller didCreateTache:(Tache *)tache;

@end

@interface CreationTacheViewController : UIViewController <UITextViewDelegate>

@property (nonatomic, retain) id <CreateTacheDelegate> delegate;
@property (strong, nonatomic) IBOutlet UITextField *titreTache;
@property (strong, nonatomic) IBOutlet UIDatePicker *dateDebut;
@property (strong, nonatomic) IBOutlet UIDatePicker *dateFin;
@property (strong, nonatomic) IBOutlet UITextView *descriptionTache;
- (IBAction)creerTache:(id)sender;
- (IBAction)cancel:(id)sender;
- (IBAction)titreReturn:(id)sender;
- (id)initWithDelegate:(id)delegate;
@end
[---]

et enfin le code de la classe "CreationTacheViewController.m" :

#import "CreationTacheViewController.h"
#import "AppDelegate.h"

@interface CreationTacheViewController ()

@end

@implementation CreationTacheViewController
@synthesize titreTache;
@synthesize dateDebut;
@synthesize dateFin;
@synthesize descriptionTache;
@synthesize delegate = _delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    descriptionTache.delegate = self;
    
    self.title = @"Création d'une tâche";
}

- (void)viewDidUnload
{
    [self setTitreTache:nil];
    [self setDateDebut:nil];
    [self setDateFin:nil];
    [self setDescriptionTache:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown && interfaceOrientation != UIInterfaceOrientationPortrait);
}

- (IBAction)creerTache:(id)sender
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    
    if ([titreTache.text isEqualToString:@""])
    {
        UIAlertView *alertTitre = [[UIAlertView alloc] initWithTitle:@"Titre" message:@"Titre de la tâche non renseigné" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertTitre setAlertViewStyle:UIAlertViewStyleDefault];
        [alertTitre show];
    }else if (dateDebut.date > dateFin.date)
    {
        UIAlertView *alertDate = [[UIAlertView alloc] initWithTitle:@"Date" message:@"La date de fin doit être supérieur à la date de début" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertDate setAlertViewStyle:UIAlertViewStyleDefault];
        [alertDate show];
    }else if ([descriptionTache.text isEqualToString:@""])
    {
        UIAlertView *alertDescription = [[UIAlertView alloc] initWithTitle:@"Date" message:@"Description de la tache non renseigné" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertDescription setAlertViewStyle:UIAlertViewStyleDefault];
        [alertDescription show];
    }else
    {
        //Créer un nouveau projet ou une nouvelle tache
        Tache *tache = (Tache *)[NSEntityDescription insertNewObjectForEntityForName:@"Tache" inManagedObjectContext:appDelegate.managedObjectContext];
        tache.titre = titreTache.text;
        tache.dateDebut = dateDebut.date;
        tache.dateFin = dateFin.date;
        tache.descritption = descriptionTache.text;
        tache.realisee = NO;
        NSError *error = nil;
        if (![appDelegate.managedObjectContext save:&error])
        {
            //gérer l'erreur
        }
        
        [self.delegate createTacheController:self didCreateTache:tache];
        [self.parentViewController dismissModalViewControllerAnimated:YES];
    }
}

- (IBAction)cancel:(id)sender
{
    [self.parentViewController dismissModalViewControllerAnimated:YES];
}

- (IBAction)titreReturn:(id)sender
{
    [sender resignFirstResponder];
}

- (void)textViewDidBeginEditing:(UITextView *)textView
{
    if (textView == descriptionTache)
    {
        //on anime le retour de la vue
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.25];
        //on déplace la vue vers le haut
        self.view.transform = CGAffineTransformMakeTranslation(0.0, -300);
        [UIView commitAnimations];
    }
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    if (textView == descriptionTache)
    {
        // on déplace la vue en même temps que le clavier pour qu’il ne cache pas le text field
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.25];
        // on remet la vue à son état initial
        self.view.transform = CGAffineTransformIdentity;
        [UIView commitAnimations];
    }
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if ([text isEqualToString:@"\n"])
    {
        [textView resignFirstResponder];
    }
    return YES;
}

- (id)initWithDelegate:(id)p_delegate
{
    self = [super init];
    if( self )
    {
        self.delegate = p_delegate;
    }
    return self;
}

@end
voila en espérant que cela puisse aider a trouver le problème :)

(en espérant que ce soit encore plus claire et que ça aide a trouver la problème plus facilement ;) )

Ce message a été modifié par BenArko - 01 octobre 2012 - 23:16.


#11 ihackiapplephone

ihackiapplephone

    iPuP aguerri

  • Members
  • 160 Messages :
  • LocationSystem32

Posté 01 octobre 2012 - 17:15

Bonjour,

Brouillon.. utilise les balises "code" pour que l'on y voient plus claire.

Merci,
cordialement,
Julien.

Ce message a été modifié par ihackiapplephone - 01 octobre 2012 - 17:16.


#12 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 08 octobre 2012 - 12:17

personne n'a d'idée ?

#13 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 23 octobre 2012 - 15:12

Je pense que le problème vient du fait que la variable [c]_creationTacheViewController[/c] qui est défini dans la méthode [c]prepareForSegue[/c] de la classe [c]TacheViewController[/c] est supprimé par l'ARC dès que je sors de la méthode [c]prepareForSegue[/c]. Existe t-il un moyen pour que cette variable ne soit pas supprimé tout en gardant l'ARC ?

#14 horiel

horiel

    iPuP novice

  • Members
  • 35 Messages :
  • LocationParis

Posté 24 octobre 2012 - 01:00

Essaye de remplacer _creationTacheViewController par self.creationTacheViewController

Car sinon tu passes pas par le setter et tu retain rien du tout.

#15 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 24 octobre 2012 - 17:03

j'ai tester ce que tu suggérais horiel mais ça ne change rien la variable est toujours supprimer une fois que l'on sort de la méthode.

#16 DricABrac

DricABrac

    iPuP maître

  • Moderators
  • 1926 Messages :

Posté 25 octobre 2012 - 16:45

Salut !

Peut être essayer de faire :
self.creationTacheViewController = [[CreationTacheViewController alloc] initWithDelegate:self];


#17 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 25 octobre 2012 - 16:49

J'ai déjà testé mais ça change rien

Ce message a été modifié par BenArko - 25 octobre 2012 - 16:50.


#18 DricABrac

DricABrac

    iPuP maître

  • Moderators
  • 1926 Messages :

Posté 25 octobre 2012 - 17:01

Ah oui pardon j'avais pas vu le post d'avant !!

Je ne comprends pas trop, en fait tu crées ton creationTacheViewController et au moment d'appeler
[self.delegate createTacheController:self didCreateTache:tache];
, ton delegate est à nil ! c'est ça ?

#19 BenArko

BenArko

    iPuP débutant

  • Members
  • 22 Messages :

Posté 25 octobre 2012 - 17:23

Oui c'est ça et même le delegate est toujours à nil du moment que l'on exécute le code de la classe creationTacheViewController. Si besoin est je peux fournir plus de code voir le projet.

#20 DricABrac

DricABrac

    iPuP maître

  • Moderators
  • 1926 Messages :

Posté 26 octobre 2012 - 14:45

Salut !

Ok et donc après quand tu fais ton init avec ton delegate, tu es sur que ton delegate prend une valeur ?
Sinon peut être essayer de le caster
- (id)initWithDelegate:(id)p_delegate
{
self = [super init];
if( self )
{
self.delegate = (id <CreateTacheDelegate>)p_delegate;
}
return self;
}





0 utilisateur(s) en train de lire ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)