Como obter a largura e a altura da tela no iOS?

506

Como obter as dimensões da tela no iOS?

Atualmente, eu uso:

lCurrentWidth = self.view.frame.size.width;
lCurrentHeight = self.view.frame.size.height;

dentro viewWillAppear:ewillAnimateRotationToInterfaceOrientation:duration:

A primeira vez que recebo o tamanho da tela inteira. A segunda vez que recebo a tela menos a barra de navegação.

griotspeak
fonte

Respostas:

1063

Como obter as dimensões da tela no iOS?

O problema com o código que você postou é que você conta com o tamanho da visualização para corresponder ao tamanho da tela e, como você viu, nem sempre é esse o caso. Se você precisar do tamanho da tela, observe o objeto que representa a própria tela, assim:

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

Atualização para exibição dividida: nos comentários, Dmitry perguntou:

Como posso obter o tamanho da tela na exibição dividida?

O código fornecido acima informa o tamanho da tela, mesmo no modo de tela dividida. Quando você usa o modo de tela dividida, a janela do seu aplicativo muda. Se o código acima não fornecer as informações que você espera, então, como o OP, você está vendo o objeto errado. Nesse caso, porém, você deve olhar para a janela em vez da tela, assim:

CGRect windowRect = self.view.window.frame;
CGFloat windowWidth = windowRect.size.width;
CGFloat windowHeight = windowRect.size.height;

Swift 4.2

let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width
let screenHeight = screenRect.size.height

// split screen            
let windowRect = self.view.window?.frame
let windowWidth = windowRect?.size.width
let windowHeight = windowRect?.size.height
Caleb
fonte
7
A orientação é realmente gerenciada no nível do controlador de exibição. Dê uma olhada em Gerenciando a orientação da interface de um controlador de exibição . Então, sim, observe a propriedade interfaceOrientation do seu controlador de exibição. BTW, você perguntou sobre o tamanho da tela, e foi isso que eu mostrei, mas para exibir seu conteúdo, você provavelmente deve usar os limites da janela ou o applicationFrame da tela, dependendo do que estiver fazendo.
Caleb
2
é útil observar que isso retorna a largura da tela inteira sem preenchimento. Basta subtrair estofamento do seu aplicativo (geralmente 20 em cada lado) a partir destes resultados para obter o espaço 'utilizável' para a maioria dos elementos
Nick Daugherty
2
@NickDaugherty Sim, esse é o ponto - o OP queria as dimensões da tela. A colocação de objetos na tela depende inteiramente de você e depende do tipo de aplicativo que você está criando. Se você estiver exibindo uma foto ou uma interface de jogo, por exemplo, talvez não deseje nenhum preenchimento.
Caleb
3
Observe, no entanto, que isso retorna um valor medido em pontos. Portanto, se você esperava a resolução da tela em pixels, o resultado estaria incorreto e você deve multiplicar o resultado por [UIScreen scale].
precisa saber é o seguinte
3
Alguém apontou que, como um CGRect pode ter largura ou altura negativa , devemos usar CGRectGetWidth()e, em CGRectGetHeight()vez de acessar diretamente o sizecampo no retângulo. Acho que nunca será um problema com relação ao retângulo da tela, mas suponho que seja algo para estar ciente.
Caleb
64

Cuidado, [UIScreen mainScreen] também contém uma barra de status. Se você deseja recuperar o quadro para o seu aplicativo (excluindo a barra de status), use

+ (CGFloat) window_height   {
    return [UIScreen mainScreen].applicationFrame.size.height;
}

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}
Ege Akpinar
fonte
4
obsoleto no ios 9.0
Zakaria Darwish 23/04
6
desde applicationFrame está obsoleta, substitua-o porreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81
44

Traduzi algumas das respostas do Objective-C acima para o código Swift. Cada tradução é prosseguida com uma referência à resposta original.

Resposta Principal

let screen = UIScreen.main.bounds
let screenWidth = screen.size.width
let screenHeight = screen.size.height

Resposta de Função Simples

func windowHeight() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.width
}

Resposta da orientação do dispositivo

var screenHeight : CGFloat
let statusBarOrientation = UIApplication.sharedApplication().statusBarOrientation
// it is important to do this after presentModalViewController:animated:
if (statusBarOrientation != UIInterfaceOrientation.Portrait
    && statusBarOrientation != UIInterfaceOrientation.PortraitUpsideDown){
    screenHeight = UIScreen.mainScreen().applicationFrame.size.width
} else {
    screenHeight = UIScreen.mainScreen().applicationFrame.size.height
}

Resposta do log

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")
Martin Woolstenhulme
fonte
Parece que há um erro de digitação no log Resposta: Deveria ser UIScreen.mainScreen (). Bounds.size.width? Eu recebo um erro de compilação sem os "limites".
stone
@skypecakes Corrigi a resposta para incluir ".bounds". Obrigado pelo feedback.
Martin Woolstenhulme
applicationFrame foi descontinuado no iOS 9 e superior, substitua porreturn UIScreen.mainScreen().bounds].size.width
Suhaib 7/16
39

Eu usei esses métodos de conveniência antes:

- (CGRect)getScreenFrameForCurrentOrientation {
    return [self getScreenFrameForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

- (CGRect)getScreenFrameForOrientation:(UIInterfaceOrientation)orientation {

    CGRect fullScreenRect = [[UIScreen mainScreen] bounds];

    // implicitly in Portrait orientation.
    if (UIInterfaceOrientationIsLandscape(orientation)) {
      CGRect temp = CGRectZero;
      temp.size.width = fullScreenRect.size.height;
      temp.size.height = fullScreenRect.size.width;
      fullScreenRect = temp;
    }

    if (![[UIApplication sharedApplication] statusBarHidden]) {
      CGFloat statusBarHeight = 20; // Needs a better solution, FYI statusBarFrame reports wrong in some cases..
      fullScreenRect.size.height -= statusBarHeight;
    }

    return fullScreenRect;
} 
Luke Mcneice
fonte
Solução agradável, mas tenha cuidado para que o temp pareça ter origem indefinida.
szemian
4
Você recebe 0,0 como padrão? Quando registrei o fullScreenRect, ele me forneceu: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Eu escolhi inicializar com CGRect temp = CGRectZero;
22412 szemian
1
UIInterfaceOrientationIsLandscape não manipula 'UIDeviceOrientationFaceUp' e 'UIDeviceOrientationFaceDown' que podem ser retornados do UIDevice.
Andriy
6
Você pode usar a propriedade screen.applicationFrame em vez de screen.bounds, que cuida da barra de status.
Geraud.ch 9/10/12
Acontece que, em alguns casos applicationFrame quadro dosn't retorno com uma barra de status corretamente subtraído (modais tela cheia de uma SPLITVIEW)
Luke McNeice
15

Percebo que este é um post antigo, mas às vezes acho útil definir # constantes como essas, para que não precise me preocupar com isso:

#define DEVICE_SIZE [[[[UIApplication sharedApplication] keyWindow] rootViewController].view convertRect:[[UIScreen mainScreen] bounds] fromView:nil].size

A constante acima deve retornar o tamanho correto, independentemente da orientação do dispositivo. Em seguida, obter as dimensões é tão simples quanto:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;
Um usuário aleatório
fonte
Você pode basear a macro na resposta do AnswerBot, pois essa parece ser a melhor resposta.
griotspeak
13

É muito, muito fácil obter o tamanho do seu dispositivo e levar em consideração a orientação:

// grab the window frame and adjust it for orientation
UIView *rootView = [[[UIApplication sharedApplication] keyWindow] 
                                   rootViewController].view;
CGRect originalFrame = [[UIScreen mainScreen] bounds];
CGRect adjustedFrame = [rootView convertRect:originalFrame fromView:nil];
memmons
fonte
Olá, eu uso isso no viewDidLoad em um aplicativo exclusivo para iPad, existe alguma razão pela qual ele obtém o valor correto pela primeira vez e, em seguida, o valor 'vira' em cada carregamento depois disso, ou seja, ele é lido como a primeira visualização da paisagem, então eu navegue para longe e volte para a vista e pareça lê-la como retrato mesmo que nenhuma mudança de orientação tenha sido feita? Graças
craigk
@LukeMcneice No meu código de produção, eu tenho uma afirmação para garantir que um quadro seja encontrado ... Eu ainda tenho essa afirmação falhada. O que está sendo retornado para rootView e originalFrame?
memmons
Estou usando esta técnica em um singleton para obter a largura / altura corrigida pela orientação. No entanto, se esse código for executado enquanto uma janela UIAlert mostrando o convertRect retornará ajustadoFrame com um tamanho (largura pelo menos) igual a 0. Alguma idéia do que está acontecendo com isso?
Coelho
Ah Um UIAlertViewirá se inserir como a visualização rootViewController da keyWindow. Eu tenho uma lógica que evita a caixa do canto porque, se uma exibição de alerta estiver ativa, o usuário não poderá interagir com o teclado, portanto, normalmente não há necessidade de pegar o quadro do teclado naquele momento.
memmons
Obrigado pela compreensão. Eu estava usando sua técnica em um banner de anúncio único. Era uma maneira simples e agradável de informar à API do anúncio o tamanho da moldura da tela para um novo anúncio. Como não poderei excluir mutuamente anúncios em banner e os do UIAlert, provavelmente voltarei a detectar paisagem versus retrato e força bruta alternando x / y conforme necessário.
Electro-Bunny
9

Temos que considerar também a orientação do dispositivo:

CGFloat screenHeight;
// it is important to do this after presentModalViewController:animated:
if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown){
    screenHeight = [UIScreen mainScreen].applicationFrame.size.height;
}
else{
    screenHeight = [UIScreen mainScreen].applicationFrame.size.width;
}
Oleh Kudinov
fonte
Boa solução Fiz isso para que meu aplicativo para iPad funcionasse em paisagem de dentro de um controlador de exibição incorporado ao apresentar um VC modal.
StackRunner
8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);
Gaurav Gilani
fonte
5

Aqui eu atualizei para o swift 3

applicationFrame descontinuado do iOS 9

Em rápida três eles removeram () e eles mudaram alguns convenção de nomeação, você pode consultar aqui Ligação

func windowHeight() -> CGFloat {
    return UIScreen.main.bounds.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.main.bounds.size.width
}
karthikeyan
fonte
4

A resposta moderna:

se o seu aplicativo oferecer suporte à exibição dividida no iPad, esse problema se tornará um pouco complicado. Você precisa do tamanho da janela, não da tela, que pode conter 2 aplicativos. O tamanho da janela também pode variar durante a execução.

Use o tamanho da janela principal do aplicativo:

UIApplication.shared.delegate?.window??.bounds.size ?? .zero

Nota: O método acima pode obter um valor errado antes que a janela se torne a janela principal ao iniciar. se você precisar apenas de largura, o método abaixo é muito recomendado :

UIApplication.shared.statusBarFrame.width

A solução antiga usando UIScreen.main.boundsretornará os limites do dispositivo. Se seu aplicativo estiver sendo executado no modo de exibição dividida, ele obterá as dimensões incorretas.

self.view.window na resposta mais quente, o tamanho pode ficar errado quando o aplicativo contiver 2 ou mais janelas e a janela tiver tamanho pequeno.

leavez
fonte
4

Utilize-os Structspara saber informações úteis sobre o dispositivo atual no Swift 3.0

struct ScreenSize { // Answer to OP's question

    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)

}

struct DeviceType { //Use this to check what is the device kind you're working with

    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_SE         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_7          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_7PLUS      = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_X          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0

}


struct iOSVersion { //Get current device's iOS version

    static let SYS_VERSION_FLOAT  = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS7               = (iOSVersion.SYS_VERSION_FLOAT >= 7.0 && iOSVersion.SYS_VERSION_FLOAT < 8.0)
    static let iOS8               = (iOSVersion.SYS_VERSION_FLOAT >= 8.0 && iOSVersion.SYS_VERSION_FLOAT < 9.0)
    static let iOS9               = (iOSVersion.SYS_VERSION_FLOAT >= 9.0 && iOSVersion.SYS_VERSION_FLOAT < 10.0)
    static let iOS10              = (iOSVersion.SYS_VERSION_FLOAT >= 10.0 && iOSVersion.SYS_VERSION_FLOAT < 11.0)
    static let iOS11              = (iOSVersion.SYS_VERSION_FLOAT >= 11.0 && iOSVersion.SYS_VERSION_FLOAT < 12.0)
    static let iOS12              = (iOSVersion.SYS_VERSION_FLOAT >= 12.0 && iOSVersion.SYS_VERSION_FLOAT < 13.0)

}
badhanganesh
fonte
3

Se você deseja largura / altura da tela, independentemente da orientação do dispositivo (bom para dimensionar retrato, apenas visualize controladores sendo iniciados a partir de orientações de paisagem):

CGFloat screenWidthInPoints = [UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale;
CGFloat screenHeightInPoints = [UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale;

[UIScreen mainScreen] .nativeBounds <- Dos documentos -> O retângulo delimitador da tela física, medido em pixels. Esse retângulo é baseado no dispositivo em uma orientação de retrato para cima. Este valor não muda à medida que o dispositivo gira.

John Erck
fonte
2

Aqui está uma maneira rápida de obter tamanhos de tela:

print(screenWidth)
print(screenHeight)

var screenWidth: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.width
    } else {
        return UIScreen.mainScreen().bounds.size.height
    }
}

var screenHeight: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.height
    } else {
        return UIScreen.mainScreen().bounds.size.width
    }
}

var screenOrientation: UIInterfaceOrientation {
    return UIApplication.sharedApplication().statusBarOrientation
}

Eles estão incluídos como uma função padrão em:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
fonte
1

CGFloat width = [[UIScreen mainScreen] bounds].size.width; CGFloat height = [[UIScreen mainScreen]bounds ].size.height;

Himanshu jamnani
fonte
1

swift 3.0

para largura

UIScreen.main.bounds.size.width

para altura

UIScreen.main.bounds.size.height
Amul4608
fonte
-2

Você pode colocar essas macros no arquivo pch e usá-las em qualquer lugar do projeto usando "SCREEN_WIDTH"

#define SCREEN_WIDTH                ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)

e "SCREEN_HEIGHT"

#define SCREEN_HEIGHT               ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation ==   UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)

Exemplo de uso:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;
Anny
fonte
Você pode recuar seu código de acordo com o formato de remarcação? Atualmente, isso foi sinalizado como "baixa qualidade" pelos usuários da comunidade na fila de revisão.
Manoj Kumar