UiviewController criado com initwithnibName: pacote: ou através de um iboutlet se comportará de maneira diferente

StackOverflow https://stackoverflow.com/questions/2257124

Pergunta

Encontrei um comportamento estranho e gostaria de explicar que afirmação estou fazendo isso está errado.

Em uma classe AppDelegate de um projeto recém -criado, estou adicionando um UIViewController à janela.
Eu posso fazer isso de duas maneiras diferentes:
- com um iboutlet. No IB, simplesmente inspirei um UIViewController, defino sua classe como testViewController e conectei -o (cenário A do código).
- Criando o UIViewController com o código (cenário B).

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    

#define USE_IBOUTLET YES // Comment this line to switch to scenario B

#ifdef USE_IBOUTLET
    // Scenario A

    [window addSubview:theTestViewController.view];
    [window makeKeyAndVisible];
#endif


#ifndef USE_IBOUTLET
    // Scenario B

    TestViewController *theTestViewControllerProgrammatically;

    theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];

    // According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
    [theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];

    [window addSubview:theTestViewControllerProgrammatically.view];

    [window makeKeyAndVisible];
#endif
}

Como não fiz nenhuma personalização do objeto no IB, devo ter o mesmo comportamento em ambos os cenários.

O cenário A, usando o iboutlet funciona conforme o esperado.
Mas o cenário B tem os seguintes problemas:
- A vista não está na posição correta (20 pixels a alta e coberta pela barra de status).
- A visualização não redimensiona corretamente (por exemplo, tente alternar a barra de status na chamada)

Por quê?

Arquivo ZIP do projeto aqui se você quiser reproduzir o problema: http://dl.dropbox.com/u/1899122/code/protowindowbasedstrangeness.zip

Foi útil?

Solução

Isso vai parecer realmente bobo após minhas respostas longas, mas o problema que você está tendo é simples de corrigir (programaticamente).

Está linha:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];

Deveria realmente ser:

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];

Você estava definindo o quadro para o VC definido pelo IB, não pelo que você criou programaticamente.

De qualquer forma - vale a pena notar que todos os meus comentários ainda se aplicam! Ainda existem algumas coisas que você terá que fazer programaticamente se não usar objetos controladores do IB (por exemplo, configurar os itens da barra de navegação)

Paulo

Outras dicas

Eu tenho tido um problema muito semelhante a você, pois notei que os objetos VC não são todos criados iguais! O problema que estou tendo é definir os itens da barra de navegação, eu simplesmente não consigo fazê -lo quando o proprietário do arquivo é um objeto de controlador de exibição que instanciou programaticamente. Funciona apenas se eu eu não mencionar os objetos do controlador do IB.

Eu baixei seu projeto e tive uma brincadeira com ele, e isso me fez pensar um pouco mais sobre o que poderia estar acontecendo. Eu acho que posso fornecer uma resposta razoável, mas não tenho certeza se existe uma solução simples ...

O que eu acredito que está acontecendo é que a Apple criou esses objetos controladores no IB que são um pouco mais especializados. Uma sugestão que isso pode ser verdade é que os objetos ib vc têm um atributo que você pode definir que não possui uma propriedade correspondente direta para uma classe UIViewController que eu possa ver, para que os objetos do controlador do IB possam ter alguma funcionalidade adicional que as subclasses não-IB UIViewController não podem tirar proveito de. Dado que os objetos em um .xib são objetos completos de 'congelamento', a Apple pode ter incluído todos os tipos de atributos privados que não podemos ver ou usar em suas versões IB deles - isso pode ter algum efeito sobre como os objetos são inicializados .

Por exemplo, em seu MainWindow.xib, selecione o objeto IB VC e você pode definir atributos na paleta do inspetor, como "redimensionar a visualização da ponta". Se você não verificar isso e executar novamente seu aplicativo, verá o VC aparecer exatamente como no cenário B. Como você não pode verificar este item quando dos atributos do proprietário do arquivo (mesmo que seja como um UIViewController ), você não consegue aproveitar o que está sendo feito pelo controlador de exibição para fornecer o comportamento que deseja.

O resultado disso é que quando você usa TestViewController.xib Para inicializar seu objeto VC no código, nenhum dos atributos específicos do IB de um VC é definido; portanto, um UIViewController é criado e, portanto implementou -se.

Ainda não encontrei uma maneira de tirar proveito da funcionalidade que os controladores de visão do IB têm quando os instantando usando initWithNibName:bundle:nibBundle (Acho que são tudo o que não podemos acessar), mas espero que isso possa ter lhe dado um ponto de partida ...

Claro, eu poderia estar completamente errado e alguém me fará parecer um idiota completo!

Paulo

Provavelmente, no caso de B, essa visão não está ciente da presença de uma barra de status. Você precisa redimensioná -lo de acordo e ajustar sua posição para levar em consideração a barra de status. Isso é feito alterando as propriedades do quadro (tamanho) e limites (localização) de um UIView.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top