considere o seguinte cenário: Eu tenho um aplicativo baseado em storyboard. Eu adiciono um objeto ViewController ao storyboard, adiciono os arquivos de classe para este ViewController ao projeto e especifico o nome da nova classe no inspetor de identidade da IB. Agora, como vou me referir a este ViewController programaticamente a partir do AppDelegate? Fiz uma variável com a classe relevante e a transformei em uma propriedade IBOutlet, mas não vejo nenhuma maneira de poder me referir ao novo ViewController no código - qualquer tentativa de arrastar uma conexão com a tecla Ctrl não funciona .
ou seja, dentro do AppDelegate, posso acessar o ViewController base como este
(MyViewController*) self.window.rootViewController
mas e qualquer outro ViewController contido no storyboard?
iphone
objective-c
ios
uiviewcontroller
storyboard
Matthias D
fonte
fonte
Respostas:
Dê uma olhada na documentação para
-[UIStoryboard instantiateViewControllerWithIdentifier:]
. Isso permite instanciar um controlador de exibição do storyboard usando o identificador que você definiu no IB Attributes Inspector:EDITADO para adicionar código de exemplo:
fonte
[[[self window] rootViewController] storyboard]
De acordo com os documentos, isso retornará o "storyboard do qual o controlador de exibição se originou". (ou nulo se não vier de um storyboard). Nesse UIStoryboard *, você pode usar as chamadas instanciadas mencionadas pelo @RobinSummerhill. Observe que os Storyboards instanciam novas instâncias dos seus viewControllers ( cenas ) conforme elas são necessárias e não reutilizam as que foram visualizadas anteriormente.Se você usa
XCode
5, deve fazê-lo de uma maneira diferente.UIViewController
emUIStoryboard
Identity Inspector
painel superior direitoUse Storyboard ID
caixa de seleçãoStoryboard ID
campoEntão escreva seu código.
fonte
Geralmente, o sistema deve lidar com a instanciação do controlador de exibição com um storyboard. O que você deseja é atravessar a hierarquia do viewController, pegando uma referência ao
self.window.rootViewController
em vez de inicializar os controladores de exibição, que já devem ser inicializados corretamente se você configurou seu storyboard corretamente.Então, digamos que você
rootViewController
é um UINavigationController e, em seguida, você deseja enviar algo para o seu controlador de vista superior, faça o seguinte no AppDelegatedidFinishLaunchingWithOptions
:Em Swift, se seria muito semelhante:
Você realmente não deve inicializar os controladores de exibição usando os IDs do storyboard do representante do aplicativo, a menos que queira ignorar a maneira normal como o storyboard é carregado e carregar o storyboard inteiro. Se você estiver tendo que inicializar cenas do AppDelegate, provavelmente está fazendo algo errado. Quero dizer, imagine que, por algum motivo, você deseja enviar dados para um controlador de exibição na pilha, o AppDelegate não deve estar chegando à pilha do controlador de exibição para definir dados. Isso não é da sua conta. Seu negócio é o rootViewController. Deixe o rootViewController manipular seus próprios filhos! Portanto, se eu estivesse ignorando o processo normal de carregamento de storyboard pelo sistema removendo referências a ele no arquivo info.plist, instanciaria no máximo o rootViewController usando
instantiateViewControllerWithIdentifier:
e, possivelmente, sua raiz, se for um contêiner, como um UINavigationController. O que você deseja evitar é instanciar controladores de exibição que já foram instanciados pelo storyboard. Este é um problema que vejo muito. Em resumo, discordo da resposta aceita. Ele está incorreto, a menos que os pôsteres signifiquem remover o carregamento do storyboard do info.plist, pois você carregou 2 storyboards de outra forma, o que não faz sentido. Provavelmente não é um vazamento de memória porque o sistema inicializou a cena raiz e a atribuiu à janela, mas você apareceu e a instanciaram novamente e as atribuiu novamente. Seu aplicativo está com um péssimo começo!fonte
fonte