presentModalViewController не работает

У меня возникла странная проблема при попытке представить MPMediaPickerController с помощью presentModalViewController. У меня он работал нормально, но недавно (возможно, с версии 3.1, я точно не помню, когда он работал в последний раз) MPMediaPickerController просто отказывается показывать себя. Экран остается черным, наверху нет ничего, кроме строки состояния, и я вынужден выйти из приложения.

Вот мой код:

// 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];

}

Как видите, он в основном дословно скопирован из примеров Apple с некоторыми модификациями, чтобы заставить его работать с Cocos2D. Переменная окна в коде - это окно приложения, которое сохраняется в методе инициализации:

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

Остальная часть метода работает нормально ... директор отсоединяется от окна, и появляется строка состояния. Но тогда на экране должен появиться MPMediaPickerController, а его нет. Как я уже упоминал, не так давно он работал нормально, поэтому я не понимаю, что здесь происходит.

Спасибо за любую помощь, которую вы можете предоставить.

Изменить: я заметил, что если я закомментирую эти строки:

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

[window addSubview:musicView];

и замените их на:

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

... тогда контроллер выбора отображается в том виде, в каком он должен быть. Именно так я добавил представление, когда впервые реализовал доступ к библиотеке iPod после выхода версии 3.0, поскольку он немного менее запутан, чем нынешний. Однако проблема с этим методом заключается в том, что после закрытия контроллера средства выбора все координаты касания, которые сообщаются мне при событиях касания, становятся неточными - они примерно на 20 пикселей выше, чем должны быть (портретная ориентация). не уверен, что это ошибка Cocos2D или что-то в этом роде, но это в значительной степени исключает представление контроллера непосредственно в openGLView директора.


person Mitch Lindgren    schedule 20.09.2009    source источник


Ответы (2)


Ну, наверное, я разобрался. Вот рабочий метод (я не решаюсь назвать «правильный метод») для всех, кто может оказаться в такой ситуации:

- (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];

}

Это показывает сборщик и не заставляет Директор сообщать неправильные координаты после того, как сборщик отклонен.

person Mitch Lindgren    schedule 21.09.2009
comment
Одно замечание: вам следует подумать о том, чтобы вызвать stopAnimation от Director, а не pause, это даст гораздо лучшую производительность. Приостановка может по-прежнему вызывать проблемы, если у вас есть UITableView в модальном представлении. - person Boon; 28.07.2011

У меня похожая проблема.

Я сделал настраиваемый контроллер модального представления с собственным протоколом делегата.

Я не вижу ничего отличного от примера Apple (добавление нескольких настроек для реализации делегата и его протокола, которые отсутствуют в фрагментах кода Apple).

Я вижу, что код выполняется, но на экране ничего не отображается, кроме базового представления, которое является представлением вызывающего контроллера представления.

Как вы думаете, что мешало появлению модального представления в вашем случае?

Спасибо.

- (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];
}

Может быть проблема, что модальное представление запрашивается у viewDidLoad? Я переместил код в другое место, но без изменений ...

Позже в коде: (это не должно влиять на то, почему модальное представление не отображается)

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

Ниже приведено исправление, необходимое для реализации протокола делегата. Эта информация отсутствует в коде Apple, но я не думаю, что она имеет какое-либо влияние на то, почему модальное представление не загружается.

@protocol DisclaimerViewDelegate;

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

@end

@protocol DisclaimerViewDelegate <NSObject>

- (void)disclaimerControllerFinished:(DisclaimerViewController *)disclaimerViewController;
person Yoichi    schedule 15.02.2010
comment
Хммм, вчера вечером тот же код не работал. Сегодня утром я повторно запустил XCode и повторно запустил приложение, и оно работает. Я не имею понятия почему..... - person Yoichi; 16.02.2010
comment
Я думаю, приятно слышать, что ваш код теперь работает. У меня был аналогичный опыт с iPhone SDK, когда все запускалось или прекращалось без видимой причины - это очень расстраивало. Боюсь, я не уверен, что вообще могло вызвать вашу проблему. Если вы еще этого не видели, ниже я отвечу на свой вопрос - я не уверен, что это поможет вам. В любом случае, если проблема возникнет снова, вы можете опубликовать новый вопрос по вашей проблеме, поскольку я думаю, что он немного отличается от моего (вы не используете Cocos2D, не так ли?) - person Mitch Lindgren; 16.02.2010