views:

2841

answers:

2

Hi everyone,
I'm having an odd issue trying to present an MPMediaPickerController using presentModalViewController. I had it working fine, but recently (perhaps as of 3.1, I don't exactly recall the last time it was working) the MPMediaPickerController just refuses to show itself. The screen just remains black, with nothing but the status bar at the top, and I'm forced to quit the application.

Here's my code:

// Show the music picker, allowing the user to create a playlist
- (void) showMusicPicker;
{
  [[Director sharedDirector] pause];
  [[Director sharedDirector] detach];

  musicView = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
  [window addSubview:musicView];

  musicController = [[UIViewController alloc] init];
  [musicController setView:musicView]; 
  [musicController setModalTransitionStyle: UIModalTransitionStyleCoverVertical];

  MPMediaPickerController *picker =
  [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];

  picker.delegate      = self;
  picker.allowsPickingMultipleItems = YES;
  picker.prompt      = @"Select songs to play";

  // The media item picker uses the default UI style, so it needs a default-style
  // status bar to match it visually
  [[UIApplication sharedApplication] setStatusBarHidden:NO animated: YES];

  [musicController presentModalViewController: picker animated: YES];
  [picker release];

}

As you can see, it's mostly copied verbatim from Apple's examples, with a few modifications to get it to work with Cocos2D. The window variable in the code is the application window, which is retained in the init method:

// Remember the window that the director is attached in
window = [[[[Director sharedDirector] openGLView] window] retain];

The rest of the method appears to work fine... the director detaches from the window and the status bar appears. But then the MPMediaPickerController should appear on the screen, and it doesn't. As I mentioned, it was working fine not too long ago, so I'm at a loss as to what's going on here.

Thanks for any help you can provide.

Edit: I've noticed that if I comment out these lines:

[[Director sharedDirector] pause];
[[Director sharedDirector] detach];

[window addSubview:musicView];

and replace them with:

[[[Director sharedDirector] openGLView] addSubview: musicView]

...then the picker controller is shown as it should be. This was the way I added the view when I was first implementing iPod library access after 3.0 came out, as it's a little less convoluted than the current way. However, the problem with this method is that once the picker controller is dismissed, all the touch coordinates which are reported to me on touch events become inaccurate - they're about 20 pixels higher than they should be (portrait orientation.) I'm not sure if this is a bug with Cocos2D or what, but it pretty much rules out presenting the controller directly on the Director's openGLView.

A: 

Well, I've figured it out, I guess. Here's a working method (I hesitate to say "the correct method") for anyone else who might find himself in this situation:

- (void) showMusicPicker;
{
  [[Director sharedDirector] pause];

  musicController = [[UIViewController alloc] init];
  [musicController setView:[[Director sharedDirector] openGLView]]; 
  [musicController setModalTransitionStyle: UIModalTransitionStyleCoverVertical];

  MPMediaPickerController *picker =
  [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];

  picker.delegate        = self;
  picker.allowsPickingMultipleItems = YES;
  picker.prompt      = @"Select songs to play";

  // The media item picker uses the default UI style, so it needs a default-style
  //    status bar to match it visually
  [[UIApplication sharedApplication] setStatusBarHidden:NO animated: YES];

  [musicController presentModalViewController: picker animated: YES];
  [picker release];

}

This shows the picker, and doesn't cause the Director to report improper coordinates once the picker is dismissed.

Mitch Lindgren
A: 

I am having a similar problem.

I made a custom modal view controller with its own delegate protocol.

I can see nothing different from Apple example (adding a few tweaks to implement the delegate and its protocol, which are lacking form Apple code fragments).

I can see that the code is executed, but nothing shows on the screen than the base view, which is the view of the calling view controller.

In your case, what do you think was preventing the modal view from appearing?

Thanks.

- (void)viewDidLoad 
{
    // If this is the first time.

    DisclaimerViewController *disclaimerViewController = [[DisclaimerViewController alloc]
                                                          initWithNibName:@"DisclaimerViewController" bundle:nil];
    disclaimerViewController.delegate = self;
    UINavigationController *myNavigationController = [[UINavigationController alloc]
                                                    initWithRootViewController:disclaimerViewController];
    [self presentModalViewController:myNavigationController animated:YES];
    [myNavigationController release];
    [disclaimerViewController release];

    [super viewDidLoad];
}

Could it be a problem the modal view is requested from the viewDidLoad? I moved the code to somewhere else but no change...

Later in the code: (this should not affect why modal view does not appear)

#pragma mark DisclaimerViewDelegate method
- (void)disclaimerControllerFinished:(DisclaimerViewController *)disclaimerViewController
{
    [disclaimerViewController dismissModalViewControllerAnimated:YES];
}

Below is a fix I needed to implement the delegate protocol. This info is lacking from Apple code, but I don't think that it has any influence as to why the modal view is not loaded.

@protocol DisclaimerViewDelegate;

@interface DisclaimerViewController : UIViewController 
{
    id<DisclaimerViewDelegate> delegate;
}
@property (assign) id<DisclaimerViewDelegate> delegate;

@end

@protocol DisclaimerViewDelegate <NSObject>

- (void)disclaimerControllerFinished:(DisclaimerViewController *)disclaimerViewController;
Yoichi
Hmmm, last night the same code was not working. This morning, I re-launched XCode and re-run the app, and it is working. I have no idea why.....
Yoichi
That's good to hear that your code is now working, I guess. I've had similar experiences with the iPhone SDK where things start or stop working for no apparent reason - it's very frustrating. I'm afraid I'm not sure what may have caused your problem in the first place. If you didn't already see it, my answer to my own question is below - I'm not sure if it will be of any help to you. Anyway, if the problem pops up again, you may want to post a new question for your issue, as I think it's slightly different than mine (you're not using Cocos2D, are you?)
Mitch Lindgren