2010-03-31 4 views
0

J'ai créé une classe pour lancer le MailComposer afin que mon application iPhone ne dispose que d'un emplacement unique pour générer divers types d'e-mails: certains avec des pièces jointes, d'autres pas. Certains avec des adresses pré-remplies, d'autres non.iPhone MailComposer classe UIViewController dismissModalViewControllerAnimations

Je ne voulais pas que ma classe implémente UIViewController, mais elle doit donc être le délégué pour le MailComposer. Sinon, les contrôleurs de vue qui appellent ma classe doivent eux-mêmes être délégués pour le MailComposer, ce qui va à l'encontre du but. L'inconvénient de faire de ma classe un contrôleur de vue est qu'il doit être chargé à l'écran avant de pouvoir afficher le MailComposer de manière modale. Malheureusement, les contrôleurs de vue ne peuvent pas être transparents. L'effet est, tout ce qui est sur l'écran est couvert par un contrôleur de vue blanc solide pendant un moment avant l'apparition du MailComposer.

Je pourrais peut-être vivre avec cela, mais pas ceci: après que le MailComposer s'en aille, il me reste mon contrôleur vide qui occupe l'écran. Je devrais être en mesure de se débarrasser de l'intérieur lui-même en appelant ceci:

[self.parentViewController dismissModalViewControllerAnimated:NO]; 

Mais qui meurt d'une mort horrible: « Chargement 43365 cadres de pile ... »

a ma classe - une UIViewController qui pré-remplit puis lance un MailComposer - piste perdue de son parentViewController? Ce n'est pas nul, parce que j'ai testé pour ça.

Comme lancé à partir du contrôleur de vue en cours ...

// My class is called Email. 
Email *oEmail = [[[Email alloc] init] retain]; 
// Red, to remind myself that I'd like to someday learn to make it transparent. 
oEmail.view.backgroundColor = [UIColor redColor]; 
// Pre-fill whatever fields you want, and specify attachments. 
oEmail.EmailSubject = @"I am truly stumped"; 
// This has to go on screen first. 
[self presentModalViewController:oEmail animated:NO]; 
// Then this can happen, which brings up the MailComposer. 
[oEmail f_SendEmail]; 
// Commenting out the next line didn't help, so I turned it back on. 
[oEmail release]; 

intérieur de la classe, vous avez besoin du mailComposeController: didFinishWithResult: erreur: méthode pour faire disparaître le MailComposer, et pour que cela se produise, la La classe doit être MFMailComposeViewControllerDelegate. Voici ce qui se passe là-bas:

// This gets rid of the mail composer. 
[self dismissModalViewControllerAnimated:YES]; 

// This never fails to get rid of other modal view controllers when called 
// from within those controllers, but boy does it not work here. 
[self.parentViewController dismissModalViewControllerAnimated:NO]; 

Si vous pouvez m'aider, je serai vraiment reconnaissant!

+0

Notez que "Chargement de 43365 cadres de pile ..." indique une récursion infinie. Si vous regardez dans le débogueur, vous devriez voir le cycle des méthodes causant ceci. –

+1

En outre, "les contrôleurs de vue ne peuvent pas être transparents" est techniquement incorrect. Les contrôleurs de vue sont simplement des objets pour gérer la logique de vos vues. Les vues elles-mêmes peuvent être transparentes, translucides ou non en plein écran. Ce dont vous parlez, c'est la méthode -presentModalViewController: animated: qui semble placer une vue blanche opaque derrière la vue de votre contrôleur lorsqu'il glisse sur l'écran. –

Répondre

1

Au lieu d'appeler

[self.parentViewController dismissModalViewControllerAnimated:NO]; 

Je mis en place un délégué pour votre contrôleur 'email'. Un exemple de ce type de connexion peut être vu dans le modèle d'application 'FlipSide' lors de la création d'un nouveau projet.

Fondamentalement, vous mettre en place un délégué pour le contrôleur Email:

Email *oEmail = [[[Email alloc] init] retain]; 
oEmail.view.backgroundColor = [UIColor redColor]; 
oEmail.EmailSubject = @"I am truly stumped"; 
[self presentModalViewController:oEmail animated:NO]; 
[oEmail f_SendEmail]; 
[oEmail setDelegate:self]; 
[oEmail release]; 

Puis dans l'Email .h fichier:

@protocol EmailDelegate 
-(void)emailDidFinish; 
@end 

@implementation Email : UIViewController { 
     // Other stuff 
     id <EmailDelegate> delegate; 
} 

@property (nonatomic, assign) id <EmailDelegate> delegate; 

@end 

Assurez-vous @synthesize délégué, puis quand vous » êtes prêt à rejeter appel:

// This gets rid of the mail composer. 
[self dismissModalViewControllerAnimated:YES]; 

// This never fails to get rid of other modal view controllers when called 
// from within those controllers, but boy does it not work here. 
if (delegate && [delegate respondsToSelector:@selector(emailDidFinish)]){ 
    [delegate emailDidFinish]; 
} 

Et enfin, dans votre contrôleur de vue original, assurez-vous vous avez dans le fichier .h et puis avoir:

-(void)emailDidFinish { 
    [self dismissModal...]; 
} 

Espérons que cela aide.

+0

Je vais tester cela. Intrigant. Je ne me soucie vraiment pas de la délégation, car comment un objet peut-il être réellement autonome s'il doit déléguer sa responsabilité à d'autres objets? Toutefois, le MailComposer est un objet créé par Apple sans module de code associé dans lequel nous pouvons ajouter du code personnalisé. Donc, nous faisons un autre objet le délégué, puis pouvons écrire notre code là-bas. Le problème est, vous devez mettre ce code dans chaque ViewController qui pourrait afficher un MailComposer. Je ne peux pas dire si votre solution proposée répond à cela jusqu'à ce que je teste. –

0

J'ai eu le même problème et je l'ai résolu d'une manière différente.

J'ai créé une fonction qui affiche le ViewController actuel. En h:

-(void)ics; 

Dans le cpp:

-(void)ics{ 
    //[self.navigationController popViewControllerAnimated:NO]; 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
} 

et l'a appelé après avoir rejeté la MailComposer:

[self dismissModalViewControllerAnimated:YES]; 
[self ics]; 

le tour est joué!

Questions connexes