Okay, well I didn't get any response - but I have been asked if I did get it working, and if I could share. So for those who are struggling with joining the dots - here is what I have. Didn't quite go with above, though I am sure I used some of it, and I didn't quite go with stuff from other posts - though there were a few really good helps out there. Gathered a bit off Apple directly, and made some up. Maybe not the best way to do it - but maybe it will be helpful for some. Note, I have recently discovered the joys of NSNotification - and I am probably over using it - but it does make what I was trying to do here easier. If you have not seen them used - they are really worth it. Though I have not tested on a device yet - so I maybe completely disappointed with performance hit.
Files:
MailViewController.h/m
EmailScene.h/m
PauseMenuLayer.h/m
MailViewController is required so that your UIViewController rotates to Landscape mode. Somehow I had this all working without doing that, but then when I came to submit my app - it stopped working! So after a bit of trial and error - this finally worked for me.
// MailViewController.h
#import <Foundation/Foundation.h>
@interface MailViewController : UIViewController {
}
@end
// MailViewController.m
#import "MailViewController.h"
@implementation MailViewController
- (id) init {
self = [super init];
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
@end
EmailScene is the heart of the solution
// EmailScene.h
#import "cocos2d.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
@class MailViewController;
@interface EmailScene : CCScene <MFMailComposeViewControllerDelegate>
{
UILabel *message;
MFMailComposeViewController *picker;
UIImage *emailImage;
MailViewController* emailController;
}
@property (nonatomic, retain) UILabel *message;
@property (nonatomic, retain) UIImage *emailImage;
-(void)displayComposerSheet;
- (id) initWithImage:(UIImage *)myImage;
@end
// EmailScene.m
#import "EmailScene.h"
#import "MainMenuScene.h"
#import "MailViewController.h"
@implementation EmailScene
@synthesize message,emailImage;
- (id) init {
self = [super init];
if (self != nil) {
[self displayComposerSheet];
}
return self;
}
- (id) initWithImage:(UIImage *)myImage
{
self = [super init];
if (self != nil) {
self.emailImage = myImage;
[self displayComposerSheet];
}
return self;
}
// Displays an email composition interface inside the application. Populates all the Mail fields.
-(void)displayComposerSheet
{
[[CCDirector sharedDirector] pause];
emailController = [[MailViewController alloc] init];
[emailController setView:[[CCDirector sharedDirector] openGLView]];
picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
//Fill in the email as you see fit
[picker setSubject:@"Subject of Email"];
// Attach an image to the email
NSData *myData = [NSData dataWithData:UIImagePNGRepresentation(self.emailImage)];
[picker addAttachmentData:myData mimeType:@"image/png" fileName:@"myimage"];
// Fill out the email body text
NSString *emailBody = @"My email, from me to you!";
[picker setMessageBody:emailBody isHTML:NO];
//display the view
[[[CCDirector sharedDirector] openGLView] addSubview:picker.view];
[emailController presentModalViewController:picker animated:YES];
[picker release];
}
// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
NSLog();
[[CCDirector sharedDirector] resume];
//dismiss view after otherwise the code is not executed
NSLog();
[picker.view.superview removeFromSuperview];
[picker dismissModalViewControllerAnimated:YES];
NSLog();
//return to previous scene
[[NSNotificationCenter defaultCenter] postNotificationName:@"returnToScene" object:self];
}
@end
PauseMenuLayer is my layer that calls the email - and returns to the scene I was working on.
// PauseMenuLayer.h
#import "cocos2d.h"
#import "EmailScene.h"
#import <UIKit/UIKit.h>
@interface MySceneLayer : CCLayer {
CCColorLayer* layer;
}
-(void)onEmail:(id)sender;
-(void)returnToScene:(NSNotification *)notification;
-(void)togglePauseMenu;
@end
// PauseMenuLayer.m
#import "PauseMenuLayer.h"
@implementation PauseMenuLayer
-(id) init
{
if( (self=[super init] )) {
CGSize windowSize = [[CCDirector sharedDirector] winSize];
layer = [CCColorLayer layerWithColor: ccc4(0x1B, 0x1B, 0x1F, 0x0)
width: windowSize.width
height: windowSize.height];
layer.isRelativeAnchorPoint = YES;
layer.position = ccp(-windowSize.width,-windowSize.height);
[self addChild: layer z:1 tag:1];
CCMenuItem *tbEmail = [CCMenuItemFont itemFromString:@"Email" target:self selector:@selector(onEmail:)];
CCMenu *menu = [CCMenu menuWithItems:tbEmail,nil];
[layer addChild:menu z:4];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(returnToScene:) name:@"returnToScene" object:nil];
}
return self;
}
-(void)returnToScene:(NSNotification *)notification
{
[self togglePauseMenu];
}
-(void)onEmail:(id)sender
{
UIImage * theImage = [self.target getUIImageFromBuffer];
EmailScene *emailScene = [[EmailScene alloc] initWithImage:theImage];
}
- (void) togglePauseMenu
{
CGSize s = [[CCDirector sharedDirector] winSize];
CGFloat showPositionX = s.width/2;
CGFloat showPositionY = s.height/2;
if (layer.position.y == showPositionY)
{
// Layer is in show position, so hide it
layer.position = ccp(showPositionX, -showPositionY);
}
else {
// layer is in hidden position, so show it
layer.position = ccp(showPositionX, showPositionY);
[layer setOpacity:0xD0];
}
}
@end
Just as an added bonus :) You can add the PauseMenuLayer to your own app by adding the following in the right places to your scene:
//In the .h file Import it
#import "PauseMenuLayer.h"
// Create a variable for it
PauseMenuLayer *pauseMenuLayer;
// and a property
@property (nonatomic, retain) PauseMenuLayer *pauseMenuLayer;
//In the .m file synthesize it
@synthesize pauseMenuLayer;
// in the init method - initalize it
pauseMenuLayer = [[PauseMenuLayer alloc] init];
[self addChild:pauseMenuLayer z:5];
// When you want to pause or unpause - send it the toggle signal
-(void)onPause:(id)sender
{
[pauseMenuLayer togglePauseMenu];
}
Okay, hope that helps someone - let me know if you need more info.
Justin