#ios #view #hierarchy #iad #rootview
#iOS #Вид #иерархия #iad #rootview
Вопрос:
Я получаю предупреждение, связанное с моим использованием GKTurnBasedMatchmakerViewController и BannerViewController для iAd. Это предупреждение:
Presenting view controllers on detached view controllers is discouraged <RootViewController: 0x14cd143c0>
Что не так с показанной ниже последовательностью кода, которая вызывает это предупреждение?
В AppDelegate.h
@interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
}
В AppDelegate.m
- (void) applicationDidFinishLaunching:(UIApplication*)application {
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
[window setRootViewController:viewController];
[window addSubview: viewController.view];
}
Затем, когда пользователь нажимает кнопку воспроизведения на моем главном экране, я сначала открываю контроллер представления game center следующим образом (обратите внимание, что во 2-й строке задается параметр presentingViewController, равный RootViewController, который был настроен в AppDelegate):
AppDelegate * theAppDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
self.presentingViewController = theAppDelegate.viewController;
GKTurnBasedMatchmakerViewController *mmvc = [[GKTurnBasedMatchmakerViewController alloc] initWithMatchRequest:request];
[presentingViewController presentViewController: mmvc animated: YES completion:nil];
После выполнения приведенного выше кода загружается новая сцена. Эта сцена описана в моем GameSelectionLayer.h следующим образом:
@interface GameSelectionLayer : CCLayer <InAppStoreControlLayerDelegate> {
...
RootViewController *viewController;
AppDelegate *app;
BannerViewController *bannerViewController;
}
Затем в моем GameSelectionLayer.mm я загружаю bannerViewController onEnter следующим образом:
-(void)onEnter {
[super onEnter];
app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
viewController = [(AppDelegate *)[[UIApplication sharedApplication] delegate] viewController];
bannerViewController = [[BannerViewController alloc] initWithContentViewController:viewController];
app.window.rootViewController = bannerViewController;
}
Я получаю вышеупомянутое предупреждение при выполнении приведенного выше кода. Пожалуйста, дайте мне знать, что, по вашему мнению, я могу делать неправильно, что вызывает это предупреждение.
Ответ №1:
Проблема в том, что вы заменяете иерархию представлений контроллера представления, в котором представлен другой контроллер представления. Предупреждение «отключено» появляется при попытке представить контроллер представления из контроллера представления, который не подключен к окну или не имеет дочернего контроллера представления, подключенного к окну.
Здесь я рекомендую два подхода. Либо отключите все контроллеры представлений перед заменой корневого контроллера представления, либо, что лучше из двух вариантов, используйте другое окно с собственной иерархией контроллеров корневого представления.
Также обратите внимание, что вам не следует добавлять представление контроллера представления в качестве подвида окна. Система делает это за вас, когда вы устанавливаете контроллер представления в качестве корневого контроллера представления.
Комментарии:
1. Итак, контроллеры представлений для меня немного загадочны. Я думаю, вы говорите, что моя ошибка в методе «onEnter». Как бы вы предложили реализовать свой 2-й вариант? Что вы подразумеваете под использованием другого окна с собственной иерархией корневых представлений?
2. Это означает создание нового
UIWindow
объекта, сохранение его (это важно!), присвоениеrootViewController
свойства контроллеру представления, который вы хотите отобразить, и вызовmakeKeyAndVisible
в новом окне.3. В рамках метода «onEnter», показанного в моем вопросе, я создал новое UIWindow и сохранил его. Я установил свойство RootViewController для контроллера представления, который я хочу отобразить (а именно bannerViewController), и я сделал новое окно Keyandviewable. Это приводит к сбою, потому что я делаю RootViewController дочерним элементом bannerViewController. Другими словами, я удалил последнюю строку «onEnter» и добавил следующие строки: window = [[UIWindow alloc] initWithFrame: [[Границы главного экрана UIScreen]]; [окно setRootViewController: bannerViewController]; [окно makeKeyAndVisible];
4. Вы должны добавить его как дочерний элемент. У вас должно быть это автономно в своем собственном окне.
5. Добавить что в качестве дочернего элемента чего? Опять же, я удалил последнюю строку «onEnter» и добавил следующие строки: window = [[UIWindow alloc] initWithFrame: [[Границы главного экрана UIScreen]]; [окно setRootViewController: bannerViewController]; [окно makeKeyAndVisible];