Espera-se que os aplicativos tenham um controlador de visualização raiz no final do lançamento do aplicativo

383

Eu recebo o seguinte erro no meu console:

Espera-se que os aplicativos tenham um controlador de visualização raiz no final do lançamento do aplicativo

Abaixo está o meu application:didFinishLaunchWithOptionsmétodo:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Set Background Color/Pattern
    self.window.backgroundColor = [UIColor blackColor];
    self.tabBarController.tabBar.backgroundColor = [UIColor clearColor];
    //self.window.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"testbg.png"]];

    // Set StatusBar Color
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];

    // Add the tab bar controller's current view as a subview of the window
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

No Interface Builder, o UITabBarControllerrepresentante do é conectado ao Delegado do Aplicativo.

Alguém sabe como resolver esse problema?

ArtSabintsev
fonte
5
Faça um NSLog de self.tabBarController antes de executar a atribuição. A mensagem é acionada apenas se o controlador for nulo. Se for nulo, e você tiver verificado se suas conexões estão corretas, tente instanciar o controlador no código.
FeifanZ 25/09
tente comentar a inicialização da janela .. verifique esta resposta stackoverflow.com/a/33958144/1293445 #
6500 mohammad alabid 30/11/15

Respostas:

188

Eu tenho esse mesmo problema. Verifique seu main.m. O último argumento deve ser definido como o nome da classe que implementa o protocolo UIApplicationDelegate.

retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
sho
fonte
49
Outra opção é garantir que a classe delegada do aplicativo seja importada no main e no uso NSStringFromClass. É assim que o Xcode agora cria o arquivo main.m. Por exemplo: #import "AppDelegate.he entãoint retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
sho 21/12
10
certifique-se que self.windowé inicializado comoself.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
Raptor
11
Eu tentei as opções acima, não funcionou para mim. E eu não estou usando um Storyboard.
jowie
3
Não teve efeito para mim, a mesma mensagem "Aplicativos são esperados ..." depois de fazer a alteração. A solução foi a resposta da OrdoDei (veja acima ou abaixo) que funcionou perfeitamente.
Andrew
11
Se você vir uma exibição em branco no Simulador, mas espera-se ver o layout de um storyboard, certifique-se de se livrar do código na função de delegação raiz "aplicativo didFinishLaunchingWithOptions ...", apontado em main.m e apenas "return SIM;" iniciar.
Olivier de Jonge
435

Substituir no AppDelegate

 [window addSubview:[someController view]];

para

  [self.window setRootViewController:someController];
OrdoDei
fonte
Isso se livrou da mensagem para mim. Ainda não está mostrando uma janela subseqüente, mas isso pode ser um problema diferente. Obrigado.
Jazzmine
3
Se você estiver usando um UINavigationController, você deve primeiro [[UINavigationController] initWithRootViewController: tableViewController] e, em seguida, use o código acima [self.window setRootViewController: self.navigationController] para definir o controlador de exibição raiz da janela
emdog4
Cocos2d tem um comentário que diz "// addSubview não funciona em iOS6" Portanto, este fixa-lo para mim, como eu estou usando iOS 6.
Almo
11
A addSubviewlinha fazia parte do modelo de projeto em uma versão anterior do Xcode / iOS SDK. Se o aplicativo voltar por um longo caminho, talvez você o tenha, mesmo que não o tenha escrito.
Seva Alekseyev
Olá, estou recebendo este erro: - *** Falha na asserção em - [UIApplication _runWithMainScene: transiçãoContext: conclusão:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294 como resolver isso #
Akash Raghani 22/09
70

Eu tive o mesmo erro ao tentar alterar o primeiro controlador de exibição carregado

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

No começo, eu realmente não sabia de onde vinha o erro exatamente, então reduzi-o e descobri o que estava errado. Acontece que eu estava tentando alterar a exibição de uma exibição antes que ela realmente aparecesse na tela. A solução foi, portanto, mover esse código no viewcontroller que estava me causando problemas de

- (void)viewDidLoad

para

- (void)viewDidAppear:(BOOL)animated

e o erro parou de aparecer. Meu problema especificamente foi causado por fazer um UIAlertViewshow.

No seu caso, sugiro que você verifique o código no controlador de exibição ativo tabBarController (como provavelmente é um problema nesse controlador de exibição). Se isso não funcionar, tente definir as configurações iniciais no arquivo nib em vez de no código - ou se você quiser fazê-lo no código, tente mover o código para o método apropriado do controlador de exibição ativo tabBarController.

Boa sorte!

Warkst
fonte
11
Warkst, obrigado pela resposta. No meu caso, não consigo mover o código viewDidLoad:(sem adicionar um sinalizador), nem devo fazer isso. Independentemente disso, obrigado pela sugestão!
ArtSabintsev 23/09
2
Encontrei isso hoje e ainda bem que o fiz - o mesmo problema - estava mostrando um lançamento inicial no viewDidLoad. Alterado para viewDidAppear e funciona bem. Não tenho certeza do que a Apple obtém melhor ao mudar isso no iOS5.
precisa
Obrigado pela sugestão de que a exibição de alerta estava causando isso, o mesmo problema também aconteceu comigo.
317 Chris
11
Você poderia nos dizer qual código você precisou remover para resolvê-lo? Estou usando o meu viewDidLoadpara muitas coisas, configurando todas as coisas de primeira vez, como adicionar dados ao arquivo UITableView. Não consigo movê-lo viewDidAppear:porque só quero disparar uma vez.
jowie
11
O problema não estava na função errada. O problema era que você estava esquecendo de chamar [super viewDidLoad] em sua função viewDidLoad, efetivamente eliminando a carga da ponta. A mesma coisa aconteceu comigo mais de uma vez.
usar o seguinte código
47

Eu entendi isso ao iniciar com o modelo "Aplicativo vazio" e depois adicionar manualmente um XIB. Eu o resolvi definindo o nome principal da ponta, como sugerido por Sunny. A etapa que falta neste cenário é remover

self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

de

application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Como ele substituirá a instância da sua janela criada no arquivo Xib. Isso pressupõe que você criou um ViewController e o conectou à sua janela e ao App Delegate no arquivo XIB também.

jlujan
fonte
Isso corrigiu para mim também. Eu estava usando um aplicativo com guias com um Storyboard no qual estava tentando adicionar o CoreData e corri para esse problema.
Gitaarik
lol se eu adicionar isso, recebo dois avisos de que as janelas do aplicativo devem ter um controlador de visualização raiz !!
George Asda
46

Isso aconteceu comigo. Resolvido editando o arquivo .plist. Especifique o nome da base do arquivo da ponta principal (deve ser MainWindow.xib). Espero que isso ajude.

insira a descrição da imagem aqui

ensolarado
fonte
2
Isso funcionou para mim! Isso funciona quando você cria um projeto vazio no Xcode 4.2, onde nenhum MainWindow estará presente e é assim que precisamos conectá-lo.
jeevangs
O problema ocorreu quando, inadvertidamente, excluímos a linha 'Main nib file base name' do arquivo 'Info.plist'. Inserir esta linha novamente corrigiu o problema.
Rtovars
Você também pode definir isso nas propriedades do projeto. Selecione o projeto, seu destino. Você pode editá-lo em Resumo -> Informações de implantação do iPhone / iPad.
Dojman
na verdade, esse era o problema para mim, levando a vários problemas relacionados à chamada viewDidLoad e viewWillAppear duas vezes no rootViewController. No meu caso, remover esta foi a solução
whyoz
27

Encontrei o mesmo problema recentemente, ao criar um projeto com o ios5 sdk. No começo, ele estava construindo e funcionando corretamente, mas depois disso o erro apareceu.
No meu caso, a solução foi bastante simples.
O que faltava era que, de alguma forma, a propriedade Main Interface na guia de resumo do destino do meu aplicativo fosse apagada. Então eu precisava configurá-lo novamente.


Se esse não for o ponto, e se o tabBarController ainda for nulo, você sempre poderá criar programaticamente sua janela e o controlador raiz. Como substituto, adicionei o seguinte código ao meu projeto

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ 
    if (!window && !navigationController) {
        NSLog(@"Window and navigation controller not loaded from nib. Will be created programatically.");
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
        UIViewController *viewController1, *viewController2;
        viewController1 = [[[FirstViewController alloc] initWithNibName:@"FirstViewController_iPhone" bundle:nil] autorelease];
        viewController2 = [[[SecondViewController alloc] initWithNibName:@"SecondViewController_iPhone" bundle:nil] autorelease];

        self.tabBarController = [[[UITabBarController alloc] init] autorelease];
        self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
        self.window.rootViewController = self.tabBarController;

    }
    else {
        [window addSubview:[tabBarController view]];
    }
    [self.window makeKeyAndVisible];
    return YES;
}

Isso funcionará apenas se a solução do sho também estiver implementada.

denicija
fonte
24

Atualizei para o iOS9 e comecei a receber esse erro do nada. Consegui corrigi-lo, mas adicionando o código abaixo para- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *window in windows) {
    if(window.rootViewController == nil){
        UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
        window.rootViewController = vc;
    }
}
Mike Flynn
fonte
Estou curioso para saber quantas janelas seu aplicativo tinha e se todos tinham um controlador de visualização raiz. Obrigado
DrAL3X
5
NOTA : Esta resposta é uma solução alternativa e não corrige a causa raiz. Veja stackoverflow.com/a/33958144/1116061
lipka
Você é um verdadeiro herói!
User2161301
21

Nenhuma das sugestões acima resolveu meu problema. O meu era este:

Adicionar:

window.rootViewController = navigationController;

depois de:

[window addSubview:navigationController.view];

no meu appdelegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
RyeMAC3
fonte
20
  • Selecione sua "Janela" no seu arquivo Nib
  • Em "Inspetor de atributos", marque "Visível na inicialização"

imagem![]

  • Isso acontece quando seu arquivo de ponta é criado manualmente.
  • Essa correção funciona no modo normal de ponta - não no modo storyboard
urso
fonte
Isso só é encontrado no modo Storyboard, eu acho.
ArtSabintsev
Não, este projeto foi no modo de ponta regular. Esta é uma captura de tela do Modo Storyboard. "Visível no lançamento" vs. "É o controlador de exibição inicial".
bearMountain
3
Se o arquivo de ponta da janela criado manualmente e "visível no Início" estiver desmarcado por padrão, essa mensagem será exibida após o lançamento do aplicativo, isso corrige o meu problema!
ZYiOS
OH OBRIGADO !!! Finalmente, uma solução para este aviso irritante. Mesmo se você tiver makeKeyAndVisible, não resolve o problema. SOMENTE isso resolveu o aviso para mim. OBRIGADO!
tacos_tacos_tacos 28/02
'Isso acontece no modo de ponta regular - não no modo storyboard` Não é muito verdade. Estou enfrentando o mesmo problema com Storyboardtambém
thesummersign
19

como adicionar um RootViewController para iOS5

se seu aplicativo não usava um RootViewController até agora, basta criar um;) pressionando File> New> New File; selecione o UIViewController subclass nome RootViewController , desmarque a interface With XIB para o usuário (supondo que você já tenha uma) e insira esse código em seu AppDelegate :: didFinishLaunchingWithOptions

rootViewController = [[RootViewController alloc] init];
window.rootViewController = rootViewController;

com certeza - você precisa importar o RootViewController.h e criar a variável

Aqui está um bom artigo sobre o RootViewController e o AppDelegate,

rémy
fonte
O link do artigo cupsofcocoa.com está inoperante - alguma idéia se houver uma cópia em algum lugar?
Ríomhaire 24/02
11
isso mudou para binpress.com, atualizou o link na resposta
rémy
Esse é um ótimo link. Boa leitura e explica o que está acontecendo. Acabei de encontrar esse problema também usando um livro antigo (já que quero aprender primeiro o Objective-C), mas escrevendo código no XCode 7 mais recente 7, que não possui os modelos mais antigos.
21816 ibaralf
11

Eu também tive esse erro, mas diferente de qualquer uma das respostas listadas anteriormente, foi porque eu descomentei o método 'loadView' no meu controlador recém-gerado (xcode 4.2, ios5).

 //Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView  
{
}

Ele até me disse que o método era para criar a exibição programaticamente, mas eu a perdi porque parecia muito semelhante a outros métodos, como o viewDidLoad, que eu normalmente uso e não o peguei.

Para resolver, remova esse método se você não estiver criando programaticamente a hierarquia de visualizações, também conhecida como nib ou storyboard.

trcarden
fonte
Posso confirmar que isso pode causar o problema. Eu tive a mesma situação, seguindo o tutorial sobre o TableView, onde eles criam definir os delegados no loadView. Depois de mover esse código para viewDidLoad e remover o loadView, tudo começou a funcionar conforme necessário.
Eugen
Você ainda pode usar a visualização de carregamento, mas adicione [super loadView]; no seu começo.
Hermann Klecker
11
Hmm ... a documentação do loadView afirma especificamente que você não deve chamar o super método.
Joshua Sullivan
Substituí o UIViewController padrão em um storyboard e descobri que o código do modelo para criar uma subclasse UIViewController tem o loadView ativado por padrão, causando isso para mim ... desperdiçado mais de uma hora nessa coisa boba. Obrigado por postar isso!
precisa saber é o seguinte
11

Eu também tenho esses problemas. Eu tenho meu projeto executado no xcode4.2.1. Eu li todos os comentários lá em cima, mas ninguém é legal para mim. depois de um tempo, acho que comentei um pedaço de código.

//self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

então eu o descomentei. está tudo bem para mim. Espero que isso ajude vocês.

Bruce Lee
fonte
O código: "self.window = [[UIWindow assign] initWithFrame: [[UIScreen mainScreen] limites]]];" causar um erro, então eu apenas o apaguei.
precisa
11

Verifique se você tem essa função no seu representante de aplicativo.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:    (NSDictionary *)launchOptions {
   return YES;
}

Certifique-se de que didFinishLaunchingWithOptions retorne YES. Se você removeu a linha 'retornar SIM', isso causará o erro. Este erro pode ser especialmente comum com usuários de storyboard.

anticiclope
fonte
muitos elogios, é isso que eu queria (projeto vazio com storyboard)
Shtirlic
2
O mesmo aqui. Obrigado. Se você criar um aplicativo vazio, esse método será preenchido com a criação manual da janela. Isso deve ser alterado para retornar simplesmente SIM. Thx
Ben G
10

Sendo minha primeira visão MenuViewController, adicionei:

MenuViewController *menuViewController = [[MenuViewController alloc]init];
self.window.rootViewController = menuViewController;

no método App Delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
}

Isso funcionou.

cujino
fonte
10

Houve uma pequena alteração no iOS 5.0, exigindo que você tivesse um controlador de visualização raiz. Se o seu código se basear em códigos de amostra mais antigos, como GLES2Sample , nenhum controlador de exibição raiz foi criado nessas amostras de código.

Para corrigir (esse GLES2Sample, por exemplo), applicationDidFinishLaunchingcriei um controlador de visualização raiz e anexo meu glView a ele.

- (void) applicationDidFinishLaunching:(UIApplication *)application
{
  // To make the 'Application windows are expected
  // to have a root view controller
  // at the end of application launch' warning go away,
  // you should have a rootviewcontroller,
  // but this app doesn't have one at all.
  window.rootViewController = [[UIViewController alloc] init];  // MAKE ONE
  window.rootViewController.view = glView; // MUST SET THIS UP OTHERWISE
  // THE ROOTVIEWCONTROLLER SEEMS TO INTERCEPT TOUCH EVENTS
}

Isso faz o aviso desaparecer e, de outra forma, não afeta seu aplicativo.

bobobobo
fonte
9

Tente conectar o IBOutlet do controlador da barra de guias à visualização raiz no Interface Builder em vez de

self.window.rootViewController = self.tabBarController;

Mas, na verdade, eu nunca vi esse erro antes.

d.lebedev
fonte
8

Resolvi o problema fazendo o seguinte (nenhuma das outras soluções acima ajudou):

No menu suspenso associado à "Interface principal", selecione outra entrada e selecione novamente "MainWindow" e depois recrie.

insira a descrição da imagem aqui

RawMean
fonte
8

Me deparei com o mesmo problema, mas eu estava usando storyboard

Atribuindo meu storyboard InitialViewControllerà minha janela rootViewController.

No

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
...
UIStoryboard *stb = [UIStoryboard storyboardWithName:@"myStoryboard" bundle:nil];
self.window.rootViewController = [stb instantiateInitialViewController];
return YES;
}

e isso resolveu o problema.

thesummersign
fonte
7

Comecei a ter esse mesmo problema logo após atualizar para o Xcode 4.3, e somente ao iniciar um projeto do zero (ou seja, crie um projeto vazio, crie um UIViewController e, em seguida, crie um arquivo de ponta separado).

Depois de colocar TODAS as linhas que eu costumava e garantir que eu tinha as conexões corretas, continuei recebendo esse erro, e o arquivo de ponta que eu estava tentando carregar através do controlador de exibição (que foi definido como rootController) nunca foi exibido no simulador.

Eu criei um único modelo de visualização através do Xcode e o comparei com o meu código e, finalmente, encontrei o problema!

O Xcode 4.3 parece adicionar por padrão o método - (vazio) loadView; para a seção de implementação do controlador de exibição. Depois de ler atentamente os comentários, ficou claro qual era o problema. O comentário indicado para substituir o método loadView se estiver criando uma exibição programaticamente (e estou parafraseando), caso contrário, NÃO substituirá o loadView se estiver usando uma ponta. Não havia mais nada dentro desse método, então, na verdade, eu estava substituindo o método (e não fazendo nada) enquanto usava um arquivo de ponta, que dava o erro.

A SOLUÇÃO foi remover completamente o método loadView da seção de implementação ou chamar o método pai adicionando [super loadView].

Removê-lo seria melhor se o uso de um arquivo NIB como adição de qualquer outro código o substituísse.

Raz
fonte
esse era exatamente o meu problema! Eu adicionei uma implementação loadView, mas não chamei super. Fiz algumas outras alterações de código, não conseguia lembrar o que diabos eu fiz. Fiquei preso por 2 horas porque essa mudança parecia tão inócua.
LearnCocos2D
6

Eu tive essa mesma mensagem de erro no log. Eu tinha um UIAlertView pop-up no aplicativo: didFinishLaunchingWithOptions. Eu o resolvi atrasando a chamada para o alertView para permitir tempo para o controlador de exibição raiz concluir o carregamento.

No aplicativo: didFinishLaunchingWithOptions:

[self performSelector:@selector(callPopUp) withObject:nil afterDelay:1.0];

que chama após 1 segundo:

- (void)callPopUp
{
    // call UIAlertView
}
janeway
fonte
Obrigado, isso resolveu meu problema. Você deve esperar para mostrar o alerta até depois que a janela for carregada. No meu caso, acabei de fazer [alert performSelector: @selector (show) withObject: nil afterDelay: 1.0];
deepwinter
6

Eu tive o mesmo problema. Se você estiver criando um aplicativo baseado em janela "do zero" como eu, precisará fazer o seguinte: (observe, estas são as etapas para o Xcode 4.2).

0. Verifique se o delegado do aplicativo está em conformidade com o protocolo UIApplicationDelegate.

Por exemplo, suponha que nosso representante se chame MyAppDelegate. No MyAppDelegate.h, devemos ter algo como isto:

@interface MyAppDelegate : 
    NSObject <UIApplicationDelegate> // etc...

1. Especifique o delegado do aplicativo em main.m

Por exemplo,

#import "MyAppDelegate.h"

int main(int argc, char *argv[])
{
  @autoreleasepool {
    return UIApplicationMain(argc, argv,
      nil, NSStringFromClass([MyAppDelegate class]));
  }
}

2. Crie um arquivo de interface da janela principal.

Para fazer isso, clique com o botão direito do mouse no seu projeto e escolha Novo arquivo. A partir daí, escolha Janela na seção iOS -> Interface do usuário.

Depois de adicionar o arquivo ao seu projeto, vá para o resumo do projeto (clique com o botão esquerdo no projeto; clique no resumo.) Em Informações de implantação do iPhone / iPod (e na seção correspondente do iPad, se desejar) e selecione seu novo arquivo de interface na seção " Interface principal "caixa de combinação.

3. Conecte tudo no editor de interface

Selecione seu arquivo de interface na lista de arquivos para abrir o editor de interface.

Verifique se o painel Utilitários está aberto.

Adicione um novo objeto arrastando um objeto da lista Objetos no painel Utilitários para o espaço acima abaixo do objeto Janela. Selecione o objeto Clique no inspetor de identidade no painel Utilitários. Altere a classe para o delegado do aplicativo (MyAppDelegate, neste exemplo).

Exiba o inspetor de conexões para MyAppDelegate. Conecte a saída da janela à Janela que já existe no arquivo de interface.

Clique no proprietário do arquivo à esquerda e, em seguida, clique no inspetor de identidade no painel Utilitários. Mude a classe paraUIApplication

Exiba o inspetor de conexões do proprietário do arquivo. Conecte a tomada delegada ao objeto MyAppDelegate.

4. Finalmente, e muito importante, clique no objeto Window no arquivo de interface. Abra o inspetor de atributos. Verifique se "Visível na inicialização" está marcado.

Era tudo o que eu precisava fazer para que funcionasse para mim. Boa sorte!

Tom
fonte
6

Se você usar MTStatusBarOverlay, receberá esse erro.

MTStatusBarOverlay cria uma janela adicional ([[UIApplication sharedApplication] windows)) que não possui um controlador raiz.

Isso não parece causar um problema.

Vorlon confuso
fonte
Você tem certeza sobre isso? Você já testou?
Sergey Grischyov 27/12/12
Tenho certeza de que cria uma janela e de que não cria um problema nos meus aplicativos.
Vorlon confuso
Você pode definir um VC fictício como MTStatusBarOverlay para corrigi-lo.
Wesley1920:
Este foi exatamente o meu problema. Eu tinha um tipo semelhante de configuração com uma janela que foi adicionada para uma barra de notificação e, uma vez que comentei, o erro desapareceu! Parece ser inofensivo neste caso.
Aaron Zinman
6

Recebi o mesmo erro depois de substituir minha interface do usuário por um Storyboard, usando o XCode 4.6.3 e o iOS 6.1

Resolvido limpando todo o código de didFinishLaucnhingWithOptions no AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    return YES;
}
Pétur Ingi Egilsson
fonte
5

OrdoDei deu uma resposta correta e valiosa. Estou adicionando esta resposta apenas para dar um exemplo de um didFinishLaunchingWithOptionsmétodo que usa a resposta dele e também leva em consideração os comentários dos outros sobre o Navigation Controller.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Override point for customization after application launch.

    // Instantiate the main menu view controller (UITableView with menu items).
    // Pass that view controller to the nav controller as the root of the nav stack.
    // This nav stack drives our *entire* app.
    UIViewController *viewController = [[XMMainMenuTableViewController alloc] init];
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

    // Instantiate the app's window. Then get the nav controller's view into that window, and onto the screen.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // [self.window addSubview:self.navigationController.view];
    // The disabled line above was replaced by line below. Fixed Apple's complaint in log: Application windows are expected to have a root view controller at the end of application launch
    [self.window setRootViewController:self.navigationController];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}
Basil Bourque
fonte
4

Isso ocorreu para mim porque, inadvertidamente, comentei:

[self.window makeKeyAndVisible];

de

- (BOOL)application:(UIApplication*) didFinishLaunchingWithOptions:(NSDictionary*)
nicerobot
fonte
4

Consegui definir o controlador de exibição inicial na tela de resumo do xcode.

Clique no nome mais alto do projeto no gerenciador de arquivos à esquerda (ele deve ter um pequeno ícone de planta). Na coluna central, clique no nome do seu projeto em 'TARGETS' (ele deve ter um pequeno ícone de lápis 'A' ao lado). Procure em 'Informações de implantação do iPhone / iPod' e procure por 'Interface principal'. Você deve poder selecionar uma opção no menu suspenso.

RachelD
fonte
4

Além da resposta "sho", isso está correto (o quarto parâmetro de UIApplicationMain deve ser o nome do controlador principal), adiciono alguns comentários.

Recentemente, mudei o 'modelo' de um aplicativo meu usando o MainWindow.xib para construir uma janela programaticamente. O aplicativo usou um modelo mais antigo que criou essa MainWindow automaticamente. Como eu queria oferecer suporte a uma visualização de controlador diferente do XIB para iPhone 5, é mais fácil escolher o XIB certo programaticamente quando o App Delegate é criado. Também removi o MainWindow.xib do projeto.

O problema foi que eu esqueci de preencher o quarto parâmetro no UIApplication main e ESQUECI DE REMOVER o MainWindow da "Interface principal" no Resumo do projeto.

Isso causou um GRANDE problema: gerou o aviso inofensivo "Espera-se que os aplicativos ..." nos dispositivos de desenvolvimento, mas quando foi para a App Store, ele quebrou nos telefones dos consumidores, travando porque o MainWindow não estava mais no pacote! Eu tive que solicitar uma revisão acelerada para a correção de bug.

Outro sintoma é que, às vezes, um bloco branco, como um UIView em branco, aparecia às vezes quando as configurações eram alteradas e o aplicativo era colocado em primeiro plano. No iPhone 5, ficou claro que era um bloco de 320x480. Talvez o MainWindow ausente estivesse sendo criado no modo de desenvolvimento, usando o tamanho antigo. Acabei de encontrar esse bug quando os primeiros relatórios do acidente chegaram à caixa de entrada.

Instalar o aplicativo da App Store em vez do XCode mostrou que o aplicativo realmente travou, e o problema da MainWindow se revelou no log, para que eu pudesse ver que não era uma combinação especial de dispositivos + versões do IOS.

epx
fonte
4

Para adicionar à resposta de Mike Flynn, desde a atualização para o Xcode 7 e a execução do meu aplicativo em um dispositivo iOS 9, adicionei isso ao meu (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

// Hide any window that isn't the main window
NSArray *windows = [[UIApplication sharedApplication] windows];
for (UIWindow *window in windows) {
    if (window != self.window) {
        window.hidden = YES;
    }
}
Kevin_TA
fonte
Estou curioso para saber quantas janelas seu aplicativo tinha e se todos tinham um controlador de visualização raiz. Obrigado
DrAL3X
3

Esse problema ocorre quando você não possui o Interface Builder configurado corretamente.

Verifique se a janela e as saídas do viewController do App Delegate estão conectadas:

No MainWindow.xib, mantenha o controle, clique em App Delegate e arraste para o objeto Window. Selecione a janela. Mantenha o controle e selecione o delegado do aplicativo novamente, arraste para o controlador de exibição raiz e selecione viewController.

uranazo
fonte
3

Este erro também aparece quando o proprietário do arquivo MainWindow.xib está definido incorretamente.

O proprietário do arquivo é UIApplication
-> objeto inserido da classe delegada do aplicativo com a saída de janela conectada à janela

JakubKnejzlik
fonte
Criei um arquivo xib manualmente e comecei a receber esse erro. muito obrigado!
precisa saber é o seguinte