¿Cómo obtener el ancho y la altura de la pantalla en iOS?

506

¿Cómo se pueden obtener las dimensiones de la pantalla en iOS?

Actualmente, uso:

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

en viewWillAppear:ywillAnimateRotationToInterfaceOrientation:duration:

La primera vez que obtengo el tamaño completo de la pantalla. La segunda vez que obtengo la pantalla menos la barra de navegación.

griotspeak
fuente

Respuestas:

1063

¿Cómo se pueden obtener las dimensiones de la pantalla en iOS?

El problema con el código que publicó es que cuenta con que el tamaño de la vista coincida con el de la pantalla, y como ha visto, ese no es siempre el caso. Si necesita el tamaño de la pantalla, debe mirar el objeto que representa la pantalla en sí, así:

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

Actualización para vista dividida: en los comentarios, Dmitry preguntó:

¿Cómo puedo obtener el tamaño de la pantalla en la vista dividida?

El código proporcionado anteriormente informa el tamaño de la pantalla, incluso en modo de pantalla dividida. Cuando usa el modo de pantalla dividida, la ventana de su aplicación cambia. Si el código anterior no le brinda la información que espera, entonces, al igual que el OP, está buscando el objeto incorrecto. Sin embargo, en este caso, debe mirar la ventana en lugar de la pantalla, de esta manera:

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
fuente
77
La orientación se gestiona realmente en el nivel del controlador de vista. Eche un vistazo a Gestión de la orientación de la interfaz de un controlador de vista . Entonces sí, mire la propiedad interfaceOrientation de su controlador de vista. Por cierto, preguntaste sobre el tamaño de la pantalla, así que eso es lo que te mostré, pero para mostrar tu contenido probablemente deberías usar los límites de la ventana o el marco de aplicación de la pantalla, dependiendo de lo que estés haciendo.
Caleb
2
Es útil tener en cuenta que esto devuelve el ancho de pantalla completa sin relleno. Simplemente reste el relleno de su aplicación (generalmente 20 en cada lado) de estos resultados para obtener el espacio "utilizable" para la mayoría de los elementos
Nick Daugherty
2
@NickDaugherty Sí, ese es el punto: el OP quería las dimensiones de la pantalla. La ubicación de los objetos en la pantalla depende totalmente de usted y depende del tipo de aplicación que esté creando. Si está mostrando una foto o una interfaz de juego, por ejemplo, es posible que no desee ningún relleno.
Caleb
3
Sin embargo, tenga en cuenta que esto devuelve un valor medido en puntos. Entonces, si esperaba la resolución de la pantalla en píxeles, el resultado sería incorrecto y debe multiplicar el resultado por [UIScreen scale].
Robotbugs
3
Alguien señaló que, dado que un CGRect puede tener un ancho o alto negativo , deberíamos usar CGRectGetWidth()y en CGRectGetHeight()lugar de acceder directamente al sizecampo en el rectángulo. No creo que sea un problema con respecto al rectángulo de la pantalla, pero supongo que es algo a tener en cuenta.
Caleb
64

Cuidado, [UIScreen mainScreen] también contiene la barra de estado, si desea recuperar el marco para su aplicación (excluyendo la barra de estado) debe usar

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

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}
Ege Akpinar
fuente
44
en desuso en ios 9.0
Zakaria Darwish
66
dado que applicationFrame está en desuso, reemplácelo conreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81
44

He traducido algunas de las respuestas anteriores de Objective-C al código Swift. Cada traducción se realiza con una referencia a la respuesta original.

Respuesta principal

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

Respuesta de función simple

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

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

Respuesta de orientación del 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
}

Respuesta de registro

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")
Martin Woolstenhulme
fuente
Parece que hay un error tipográfico en la respuesta del registro: ¿Debería ser UIScreen.mainScreen (). Limits.size.width? Me sale un error de compilación sin los ".bounds".
piedra
@skypecakes He arreglado la respuesta para incluir ".bounds". Gracias por la respuesta.
Martin Woolstenhulme
applicationFrame está en desuso en iOS 9 y superior, reemplace conreturn UIScreen.mainScreen().bounds].size.width
Suhaib
39

He usado estos métodos de conveniencia 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
fuente
Buena solución, pero tenga cuidado de que la temperatura parece tener un origen indefinido.
szemian
44
¿Obtienes 0,0 por defecto? Cuando registré fullScreenRect, me dio: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Elegí inicializar con CGRect temp = CGRectZero;
szemian
1
UIInterfaceOrientationIsLandscape no maneja 'UIDeviceOrientationFaceUp' y 'UIDeviceOrientationFaceDown' que se pueden devolver desde UIDevice.
Andriy
66
Es posible que desee utilizar la propiedad screen.applicationFrame en lugar de screen.bounds, que se ocupa de la barra de estado.
Geraud.ch
Resulta que, en algunos casos, el marco de la aplicación no devuelve el marco con una barra de estado correctamente restada (modales de pantalla completa de una vista dividida)
Luke Mcneice
15

Me doy cuenta de que esta es una publicación antigua, pero a veces me resulta útil definir # constantes como estas, así que no tengo que preocuparme por eso:

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

La constante anterior debe devolver el tamaño correcto sin importar la orientación del dispositivo. Entonces obtener las dimensiones es tan simple como:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;
Un usuario aleatorio
fuente
Es posible que desee basar la macro en la respuesta de AnswerBot, ya que parece ser la mejor respuesta.
griotspeak
13

Es muy, muy fácil obtener el tamaño de su dispositivo , así como tener en cuenta la orientación:

// 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
fuente
Hola, yo uso esto en viewDidLoad en una aplicación de iPad solo para paisajes, ¿hay alguna razón por la cual obtiene el valor correcto la primera vez, luego el valor se 'voltea' en cada carga después de eso, es decir, lo lee como la primera vista del paisaje, luego yo navega lejos y de regreso a la vista y parece leerlo como retrato incluso si no se hizo ningún cambio de orientación? Gracias
craigk
@LukeMcneice En mi código de producción tengo una afirmación para asegurarme de que se encuentre un marco ... Todavía tengo que hacer que esa afirmación falle. ¿Qué se devuelve para rootView y originalFrame?
memmons
Estoy usando esta técnica en un singleton para obtener el ancho / alto corregido por la orientación. Sin embargo, si este código se ejecuta mientras una ventana UIAlert que muestra el convertRect devuelve ajustadoFrame con un tamaño (ancho al menos) de 0. ¿Alguna idea de lo que está sucediendo con eso?
Electro-Bunny
Ah An UIAlertViewse insertará como la vista rootViewController de keyWindow. Tengo una lógica que evita el caso de la esquina porque si una vista de alerta está activa, el usuario no puede interactuar con el teclado, por lo que generalmente no hay necesidad de tomar el marco del teclado en ese momento.
memmons
Gracias por la perspicacia. Estaba usando tu técnica en un banner publicitario singleton. Era una manera simple y agradable de decirle al anuncio api el tamaño del marco de la pantalla para un nuevo anuncio. Dado que no podré excluir mutuamente los anuncios de banner y los de UIAlert, probablemente recurriré a la detección de cambio de paisaje / vertical y fuerza bruta x / y según sea necesario.
Electro-Bunny
9

También tenemos que considerar la orientación del 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
fuente
Buena solución Hice esto para que mi aplicación iPad funcionara en horizontal desde un controlador de vista integrado cuando presentaba un VC modal.
StackRunner
8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);
Gaurav Gilani
fuente
5

Aquí he actualizado para Swift 3

applicationFrame en desuso de iOS 9

En Swift Three han eliminado () y han cambiado algunas convenciones de nomenclatura, puede consultar aquí Enlace

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

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

La respuesta moderna:

Si su aplicación admite la vista dividida en iPad, este problema se vuelve un poco complicado. Necesita el tamaño de la ventana, no el de la pantalla, que puede contener 2 aplicaciones. El tamaño de la ventana también puede variar mientras se ejecuta.

Utilice el tamaño de la ventana principal de la aplicación:

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

Nota: El método anterior puede obtener un valor incorrecto antes de que la ventana se convierta en ventana clave al iniciar. Si solo necesita ancho, se recomienda el siguiente método :

UIApplication.shared.statusBarFrame.width

La solución anterior usando UIScreen.main.boundsdevolverá los límites del dispositivo. Si su aplicación se ejecuta en modo de vista dividida, obtiene las dimensiones incorrectas.

self.view.window en la respuesta más reciente puede tener un tamaño incorrecto cuando la aplicación contiene 2 o más ventanas y la ventana tiene un tamaño pequeño.

Leavez
fuente
4

Utilice estos Structspara conocer información útil sobre el dispositivo actual en 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
fuente
3

Si desea el ancho / alto de la pantalla independientemente de la orientación del dispositivo (bueno para dimensionar los controladores de vista de solo retrato que se inician desde orientaciones horizontales):

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

[UIScreen mainScreen] .nativeBounds <- De los documentos -> El rectángulo delimitador de la pantalla física, medido en píxeles. Este rectángulo se basa en el dispositivo en una orientación vertical. Este valor no cambia a medida que el dispositivo gira.

John Erck
fuente
2

Aquí hay una forma rápida de obtener tamaños de pantalla:

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
}

Estos se incluyen como una función estándar en:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
fuente
1

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

Himanshu jamnani
fuente
1

swift 3.0

para ancho

UIScreen.main.bounds.size.width

para altura

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

Puede colocar estas macros en su archivo pch y utilizarlas en cualquier parte del proyecto utilizando "SCREEN_WIDTH"

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

y "SCREEN_HEIGHT"

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

Ejemplo de uso:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;
Anny
fuente
¿Puede sangrar su código de acuerdo con el formato de descuento? Actualmente, los usuarios de la comunidad lo marcaron como "baja calidad" en la cola de revisión.
Manoj Kumar