UISCREEN ApplicationFrame retornando retângulo incorreto no lançamento do aplicativo da paisagem (iPhone/iPad)
-
27-09-2019 - |
Pergunta
Tendo problemas para obter os limites corretos para o meu aplicativo para iPad ao iniciá -lo no modo paisagem. Eu tenho as teclas adequadas definidas no meu arquivo info.plist e meus controladores de exibição são lançados corretamente no cenário (e retrato, natch).
No meu applicationDidFinishLaunching:
Método, estou chamando um seletor após um atraso de 3 segundos, e esse método faz uma chamada para [[UIScreen mainScreen] applicationFrame]
, mas está me devolvendo uma moldura de retrato (por exemplo, altura> largura).
Alguém sabe como consertar isso? Cheira um bug para mim (se sim, eu arquivarei um radar), mas se for o comportamento pretendido, onde ele está documentado?
Solução
Quando você está segurando o iPad na orientação da paisagem e inicia um aplicativo, o controlador de exibição vê inicialmente os limites para uma visão de retrato (mesmo que a Orientation relate o cenário). O controlador de exibição receberá uma mensagem para girar para a orientação da paisagem antes de aparecer.
Outras dicas
Eu nunca confio [[UIScreen mainScreen] applicationFrame]
, especialmente durante o lançamento do aplicativo.
Ao criar visualizações no código, use a supervisão para definir seu quadro.
Se você estiver usando o XIBS com "elementos de interface simulados", eles serão de tamanho correto e tudo funcionará muito bem.
Aplicativos baseados em UinavigationController
No caso de um aplicativo baseado em uinavigationcontroller, pegue o quadro diretamente de self.navigationController.view
, não tente usar [self loadView]
e self.view.superview
. O UinavigationController usa subviews "Hidden" para fazer seu trabalho-para que a supervisão direta não funcione.
UinavigationController é especial porque durante o lançamento do aplicativo, o controlador de navegação redimensiona suas opiniões depois loadView
é chamado. Ao automoberar, você acaba com uma pequena margem na parte inferior da tela.
Por que não uiscreen
[[UIScreen mainScreen] applicationFrame]
Não funciona de maneira confiável (especialmente durante o lançamento do aplicativo no cenário). Minha experiência é que o viewcontroller interfaceOrientation
A propriedade não corresponderá ao applicationFrame
orientação.
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
É assim que eu recebo o CGrect correto quando o controlador de exibição está na paisagem:
CGRect landscapeBounds;
if (self.view.frame.size.width < self.view.frame.size.height)
landscapeBounds = CGRectMake(self.view.frame.origin.y, self.view.frame.origin.x, self.view.frame.size.height, self.view.frame.size.width);
else
landscapeBounds = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
Isso é o projetado. Você deve consultar o tamanho da sua supervisão e ajustar conforme necessário.
[[UIScreen mainScreen] applicationFrame]
Sempre retornará o retângulo de retrato, mesmo que o aplicativo esteja no modo paisagem. Isso está relacionado ao fato de que UIWindow
Nunca na verdade gira, mas apenas muda a transformação de rootViewController.view
em vez de.
Para ter certeza, você pode imprimir o objeto View Root nos modos de retrato e paisagem e verá algo assim:
Retrato:
<UIView: 0x96290e0; frame = (0 20; 768 1004); ...
Paisagem:
<UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...
Portanto, adicione uma imagem de lançamento e dê -lhe o sufixo -568h, de acordo com os guias da Apple.
Não entendo por que alguém com uma mente sólida faria uma configuração de sistema depender de um gráfico; Mas acabei de testar e funcionou.
Aqui está o local que me ensinou depois de uma pesquisa rápida Não vi essa resposta acima, imaginei que seria útil para alguém.
S
Eu tive o mesmo problema ao descartar a visualização com o DismissViewControlleRanimated no Cordova Plugin. Modifiquei o código SingingAtom para o método ViewWillappear no MainViewController, que foi redimensionado após descartar a visualização modal:
- (void)viewWillAppear:(BOOL)animated
{
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIDeviceOrientationLandscapeLeft == orientation ||
UIDeviceOrientationLandscapeRight == orientation)
{
if (appFrame.size.width < appFrame.size.height)
{
appFrame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width);
}
}
self.view.frame = appFrame;
[super viewWillAppear:animated];
}