переключение между контроллерами просмотра

#iphone #uiviewcontroller

#iPhone #uiviewcontroller — контроллер

Вопрос:

Я использовал этот метод в нескольких приложениях, которые продаются в App Store, но по какой-то причине текущее приложение, над которым я работаю, сводит меня с ума… Должно быть, я что-то упускаю из виду.

Основной файл ViewController .h приложения:

 #import "MainMenuController.h"
#import "GamePlay.h"

@interface ProjectNameiPhoneViewController : UIViewController <MenuDelegate, GameDelegate> {
      UIViewController *currentPageController;
}
 

Приложение запускается и загружает MainMenu ViewController:

 UIViewController *nextController = [[MainMenuController alloc] initWithNibName:@"MainMenuController" bundle:nil];
[nextController performSelector:@selector(setDelegate:) withObject:self];

[self.view addSubview:nextController.view];

currentPageController = nextController;
[currentPageController retain];
[nextController release];
 

Из MainMenuController.m пользователь выбирает запуск игры:

 [delegate startGameplay:self];
 

Вернитесь в главный ViewController приложения:

 - (void)startGameplay:(MainMenuController *)sender {

    UIViewController *nextController = [[GamePlay alloc] initWithNibName:@"GamePlay" bundle:nil];

    [nextController performSelector:@selector(setDelegate:) withObject:self];

    [currentPageController.view removeFromSuperview];
    [self.view addSubview:nextController.view];

    [currentPageController release];
    currentPageController = nextController;
    [currentPageController retain];
    [nextController release];
}
 

На экране игрового процесса пользователь нажимает кнопку «Назад», чтобы вернуться в главное меню:

 - (IBAction)backTapped {
    [delegate backToMenu:self];
}
 

Вернитесь в главный ViewController приложения:

 - (void)backToMenu:(GamePlay *)sender {

    UIViewController *nextController = [[MainMenuController alloc] initWithNibName:@"MainMenuController" bundle:nil];

    [nextController performSelector:@selector(setDelegate:) withObject:self];

    [currentPageController.view removeFromSuperview];
        [self.view addSubview:nextController.view];

    [currentPageController release];
    currentPageController = nextController;
    [currentPageController retain];
    [nextController release];   
}
 

Я еще раз выбираю запустить игру из главного меню.

Загружается класс игрового процесса / перо, и я еще раз нажимаю кнопку «Назад», чтобы вернуться в главное меню.

На этом этапе приложение выходит из строя, и информация не выводится на консоль.

Любые идеи будут с БЛАГОДАРНОСТЬЮ приняты — я прокомментировал почти все остальное в своем коде до такой степени, что это переключение между ViewControllers является практически единственным выполняемым кодом, и я не понимаю, почему он сбой…

Заранее большое спасибо за вашу помощь!

Комментарии:

1. Включите зомби и проверьте причину сбоя.

2. Я только что включил zombies, и при сбое приложения на консоль по-прежнему не выводится сообщение…

3. Спасибо, Вуди, но мой RootViewController запускает MainMenuController во всех моих приложениях… мой RootViewController просто действует как делегат, который переключается между различными представлениями, от основного меню до игрового процесса, кредитов и других представлений

4. Отладьте метод backToMenu для каждой строки кода и проверьте распределение объектов.

5. Теперь это отлично работает в симуляторе, хорошо работает на iPhone 4S с iOS 5 и постоянно вылетает на iPad (1-го поколения) под управлением iOS 5. Разочарование! =/

Ответ №1:

Вполне вероятно, что вы хотите использовать MainMenuController в качестве RootViewController ключевого окна вашего приложения.

Кроме того, представления UIViewController не должны добавляться к другим представлениям UIViewController, поскольку это нарушает цепочку ответчиков и в iOS 5.0 выдает исключение. Если вы решите реализовать его только как приложение для iOS 5.0, я рекомендую взглянуть на [UIViewController -addChildViewController:] и [UIViewController -removeChildViewController:]

Говоря это, лучшим решением, если оно выполнимо, было бы использовать MainMenuController в качестве RootViewController, как указано выше, а затем вызвать [UIViewController -presentModalViewController:animated:] ваш startGameplay метод и использовать делегат для отключения контроллера модального представления

Комментарии:

1. Еще раз спасибо за ваш ответ — мне определенно интересно, имеет ли проблема какое-либо отношение к iOS 5 или XCode 4.2, поскольку у меня не было проблем с этим до iOS 5… Я рассмотрю «addChildViewController» и «removeChildViewController» — вы хотите сказать, что они предназначены ТОЛЬКО для использования с iOS 5, а не с предыдущими версиями ОС?

2. и addSubview / removeFromSuperview вновь НЕ разрешены в iOS 5.0?

3. Вы продолжаете использовать addSubview и removeFromSuperview, но для сохранения цепочки UIResponder в целости используются addChildViewController / removeChildViewController . Это означает, что вращение и подобные события правильно передаются по цепочке.

4. Вложение контроллеров просмотра, подобных этому, также не поощрялось и нарушало некоторые из предположений UIViewControllers, заявленных в iOS 4 и более ранних версиях. Не должно быть слишком удивительно, что использование этого подхода вызывает неожиданное поведение в iOS 5. Я попытался объяснить это здесь: blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers если это вам как-то поможет.

Ответ №2:

Это не похоже на истинное разрешение, но приложение выходит из строя только тогда, когда я запускаю его через Xcode «build and run». Если я открою приложение, щелкнув значок на самом устройстве, приложение будет работать отлично. Я могу воспроизводить его в течение длительных периодов времени и нажимать кнопки для переключения между контроллерами просмотра снова и снова очень быстро, и он не выходит из строя. Поэтому я собираюсь отправить его в App Store, даже несмотря на то, что он каждый раз вылетает без сообщения об ошибке при запуске через Xcode — он абсолютно не зависает на самом устройстве.

Самая странная часть сбоя при запуске через Xcode заключается в следующем: приложение выходит из строя на устройстве, переходя на главный экран. Тем не менее, Xcode по-прежнему показывает приложение как «Запущенное», и у меня есть возможность нажать «Стоп» — оно не выделено серым цветом. Как я уже сказал, сообщение об ошибке не выводится на консоль.