Você pode usar algo como UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)
determinar a orientação e então usar as dimensões de acordo.
NO ENTANTO, durante uma mudança de orientação como no UIViewController
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
Use a orientação passada toInterfaceOrientation
uma vez que statusBarOrientation do UIApplication ainda apontará para a orientação antiga, pois ainda não mudou (já que você está dentro de um will
manipulador de eventos).
Resumo
Existem várias postagens relacionadas a isso, mas cada uma delas parece indicar que você deve:
- Observe
[[UIScreen mainScreen] bounds]
para obter as dimensões,
- Verifique em qual orientação você está e
- Considere a altura da barra de status (se exibida)
Links
Código de Trabalho
Normalmente não vou tão longe, mas você despertou meu interesse. O código a seguir deve resolver o problema. Eu escrevi uma categoria sobre UIApplication. Eu adicionei métodos de classe para obter o currentSize ou o tamanho em uma determinada orientação, que é o que você chamaria no UIViewController willRotateToInterfaceOrientation:duration:
.
@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end
@implementation UIApplication (AppDimensions)
+(CGSize) currentSize
{
return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
@end
Para usar o código de chamada simples [UIApplication currentSize]
. Além disso, executei o código acima, então sei que funciona e relata as respostas corretas em todas as orientações. Observe que eu levo em consideração a barra de status. Curiosamente, tive que subtrair o MIN da altura e largura da barra de status.
Espero que isto ajude. : D
Outros pensamentos
Você poderia obter as dimensões observando a rootViewController
propriedade UIWindow . Eu olhei para isso no passado e ele relata da mesma forma as mesmas dimensões em retrato e paisagem, exceto que relata ter uma transformação de rotação:
(gdb) po [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); transformar = [0, -1, 1, 0, 0, 0]; redimensionar automaticamente = W + H; camada = <CALayer: 0xf729b80 >>
(gdb) po [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); redimensionar automaticamente = W + H; camada = <CALayer: 0xf729b80 >>
Não tenho certeza de como seu aplicativo funciona, mas se você não estiver usando um controlador de navegação de algum tipo, você poderia ter um UIView sob sua visualização principal com a altura / largura máxima do pai e aumenta / diminui com o pai. Então você poderia fazer: [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]
. Isso parece muito intenso em uma linha, mas essa é a ideia.
No entanto ... Ainda seria melhor seguir as 3 etapas acima no resumo. Comece a mexer com o UIWindows e você descobrirá coisas estranhas, como mostrar um UIAlertView mudará a keywindow do UIApplication para apontar para uma nova UIWindow que o UIAlertView criou. Quem sabia? Eu fiz isso depois de encontrar um bug em keyWindow e descobrir que ele mudou assim!
applicationFrame
vez debounds
(em UIScreen), não será necessário subtrair a altura da barra de status.mainScreen().bounds.size
tornou-se dependente da orientação do iOS 8 em dianteEste é o meu código de solução! Este método pode adicionar ao Categroy da classe NSObject, ou você pode definir uma classe UIViewController personalizada Top e deixar todos os outros UIViewControllers herdá-la.
Observe , após o IOS8, como o Documento da Apple da propriedade bounds de UIScreen diz:
portanto, para consideração de compatibilidade, devemos detectar a versão do IOS e fazer a alteração conforme abaixo:
fonte
Aqui está uma macro útil:
fonte
No iOS 8+, você deve usar o
viewWillTransitionToSize:withTransitionCoordinator
método:Isso substitui o método de animação obsoleto que não fornecia informações sobre o tamanho:
fonte
A partir do iOS 8, os limites da tela agora são retornados corretos para a orientação atual. Isso significa que um iPad na orientação paisagem [UIScreen mainScreen] .bounds retornaria 768 no iOS <= 7 e 1024 no iOS 8.
O seguinte retorna a altura e largura corretas em todas as versões lançadas.
fonte
se você quiser o tamanho dependente da orientação e tiver uma visualização, pode apenas usar:
fonte
Eu escrevi categoria
UIScreen
, que funciona em todas as versões do iOS, para que você possa usá-lo como este:[[UIScreen mainScreen] currentScreenSize]
.fonte
Aqui está uma maneira rápida de obter tamanhos de tela dependentes da orientação:
Estes são incluídos como uma função padrão em um projeto meu:
https://github.com/goktugyil/EZSwiftExtensions
fonte
fonte
No entanto, no iOS 8.0.2:
fonte
use -> setNeedsDisplay () para a visão que você deseja redimensionar.
fonte