Pergunta

O objeto é responsável por dipatching as chamadas de método de rotação UIViewController, ou seja:

  • shouldAutorotateToInterfaceOrientation:
  • willRotateToInterfaceOrientation:duration:
  • willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
  • willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:
  • didRotateFromInterfaceOrientation:

Eu imagino que é UIApplication (mas talvez o AppDelegate ou UIWindow).

A próxima pergunta é como é que o objeto sabe que UIViewController para conversar?

Como ele sabe que UIViewController tem seu ponto de vista como o subexibição da janela?

Há uma mensagem que você pode enviar ou uma propriedade que você pode definir (de algum objeto), que define o UIViewController "Ativo" para o aplicativo?

Foi útil?

Solução

Parece que UIApplication está despachando uma mensagem para o controlador de exibição ativa.

Mas como é que a sua instância View Controller obter essas mensagens?

A mensagem é encaminhada para o primeiro controlador de vista cuja visão foi adicionado à instância UIWindow.

Esta se resume a 3 cenários básicos:

  1. O ViewController cuja visão é adicionado directamente ao UIWindow instância (vista único aplicativo)

  2. O controlador de navegação em um Navigation aplicativo com base, em seguida, o controlador de navegação encaminha o mensagem para o ponto de vista vistas ativa controlador.

  3. A barra de abas Controlador em uma barra de abas aplicativo com base, em seguida, a barra de abas controlador encaminha a mensagem para os pontos de vista activas ver controlador (ou o controlador de navegação ativa).

O problema que você terá, é se você criar um aplicativo com vários pontos de vista, mas não usar um controlador de navegação ou controlador Tab Bar. Se você trocar pontos de vista dentro e fora da instância UIWindow manualmente, você não vai receber essas mensagens de forma confiável. Isso é semelhante a mensagens como esta: iPhone viewWillAppear não disparar

Basta usar convenções da Apple para vários pontos de vista e você estar bem. Esperamos que esta salva alguém uma ou duas horas

Outras dicas

Como se sabe qual UIViewController tem seu ponto de vista como o subexibição da janela?

classe UIViewController mantém um mapa estático entre pontos de vista e seus vista controladores. Este mapa é consultado em alguns lugares-chave dentro CocoaTouch. Em particular, [UIView nextResponder] consultas lo e retorna o controlador se encontrado.

Eu acho que UIWindow faz a mesma pesquisa com a sua vista de raiz para saber qual controlador para eventos de rotação para frente. Irá verificar isso na próxima vez eu vou estar olhando alguma coisa na desmontagem. (Eu passei algum tempo engenharia reversa CocoaTouch para entender como as coisas funcionam lá.)

Esta é toda a magia que você não se preocupa em. Basta adicionar exibição de raiz de seu controlador para a janela - ou obter um guia ou barra de controlador de navegação para fazer isso por você -. E vai receber estas mensagens

(Mas se você picar ao redor com o depurador, você pode chegar à mesma conclusão que eu tenho:. Há algum tipo de tabela interna mapeando vista traseira de cada controlador para o controlador, e as mensagens são enviadas com base nesse link)


Update: Esta foi a magia realmente privado em 2009, quando escrevi pela primeira vez esta resposta, mas as mudanças subseqüentes para iOS fizeram as APIs por trás dela público. O controlador de vista raiz é agora acessível através da propriedade UIWindow.rootViewController, ea árvore de controladores de vista descendentes é formado usando a propriedade UIViewController.childViewControllers.

Pais controladores de vista são responsáveis ??por notificar seus filhos de mudanças de orientação. (Não tenho certeza como o controlador de vista raiz é notificado, mas você pode definir um ponto de interrupção e descobrir a si mesmo.) O método -shouldAutomaticallyForwardRotationMethods decide se UIViewController vai fazer isso por você. Se ela retorna NO, você se torna responsável por fazê-lo em seus -willRotateToInterfaceOrientation:duration:, -willAnimateRotationToInterfaceOrientation:duration: e métodos -didRotateFromInterfaceOrientation:.

Eu tenho um problema semelhante.

Eu tenho um trabalho game na orientação paisagem (tanto à esquerda e paisagem à direita).

A fim de gerir uma aplicação multi-view eu uso uma raiz UIViewController, ou seja, um manequim UIViewController com uma UIView que não faz nada. Em seguida, adicione todos os outros UIView a ele como um subview.

Ao iniciar o aplicativo, o emulador rapidamente gira a uma orientação vertical, e eu recebo cada um de meus pontos de vista com a sua estrutura de propriedade parecendo (0, -80320480). Isto resulta na vista a ser cortada por um rectângulo 160 X 320 no lado direito.

Eu tenho notado que o - shouldAutorotateToInterfaceOrientation: método de cada subexibição só é chamado uma vez, e isso acontece quando ele é adicionado à exibição de raiz. Mais tarde, ao girar o dispositivo, somente a exibição de raiz fica com o método chamado.

Sem surpresa, qualquer um dos -. WillAnimate * chama métodos só são enviados para a exibição de raiz, então, definir qualquer um destes métodos em subviews é inútil

Esses métodos são chamados toda vez que a orientação é alterada para uma orientação aceite pelo - shouldAutorotateToInterfaceOrientation: método. Então eu percebi que poderia chnage quadro propriedade dos meus subviews de lá.

Para conseguir isso, eu defini o seguinte método na minha classe RootViewController:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
    subview1_ViewController.view.frame = CGRectMake(0,0,480,320);
    subview2_ViewController.view.frame = CGRectMake(0,0,480,320);
        ...
}

Eu não entendo por que a propriedade quadro não é atualizado, mas eu sei que isso funciona solução alternativa.

Espero que isso ajude ....

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