Come ottenere la larghezza e l'altezza dello schermo in iOS?


506

Come si possono ottenere le dimensioni dello schermo in iOS?

Attualmente utilizzo:

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

in viewWillAppear:ewillAnimateRotationToInterfaceOrientation:duration:

La prima volta che visualizzo l'intera dimensione dello schermo. La seconda volta ottengo lo schermo meno la barra di navigazione.

Risposte:


1063

Come si possono ottenere le dimensioni dello schermo in iOS?

Il problema con il codice che hai pubblicato è che stai contando sulla dimensione della vista per corrispondere a quella dello schermo, e come hai visto non è sempre il caso. Se hai bisogno delle dimensioni dello schermo, dovresti guardare l'oggetto che rappresenta lo schermo stesso, in questo modo:

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

Aggiornamento per vista divisa: nei commenti, Dmitry ha chiesto:

Come posso ottenere le dimensioni dello schermo nella vista divisa?

Il codice sopra riportato riporta le dimensioni dello schermo, anche in modalità schermo diviso. Quando si utilizza la modalità schermo diviso, la finestra dell'app cambia. Se il codice sopra non ti dà le informazioni che ti aspetti, quindi come l'OP, stai guardando l'oggetto sbagliato. In questo caso, tuttavia, dovresti guardare la finestra anziché lo schermo, in questo modo:

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

Rapido 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

7
L'orientamento è veramente gestito a livello di controller di visualizzazione. Dai un'occhiata a Gestione dell'orientamento dell'interfaccia di un controller di visualizzazione . Quindi sì, guarda la proprietà interfaceOrientation del controller di visualizzazione. A proposito, mi hai chiesto delle dimensioni dello schermo, quindi è quello che ti ho mostrato, ma per visualizzare i tuoi contenuti dovresti probabilmente usare i limiti della finestra o l'applicazione Frame dello schermo, a seconda di ciò che stai facendo.
Caleb,

2
è utile notare che questo restituisce la larghezza dello schermo intero senza riempimento. Basta sottrarre l'imbottitura della tua app (di solito 20 su ciascun lato) da questi risultati per ottenere lo spazio "utilizzabile" per la maggior parte degli elementi
Nick Daugherty,

2
@NickDaugherty Sì, questo è il punto: l'OP voleva le dimensioni dello schermo. La posizione degli oggetti sullo schermo dipende interamente da te e dipende dal tipo di app che stai costruendo. Ad esempio, se stai visualizzando una foto o un'interfaccia di gioco, potresti non desiderare alcuna imbottitura.
Caleb,

3
Si noti tuttavia che ciò restituisce un valore misurato in punti. Quindi, se ti aspettavi la risoluzione dello schermo in pixel, il risultato sarebbe errato e dovresti moltiplicare il risultato per [UIScreen scale].
Robotbugs

3
Qualcuno ha sottolineato che poiché un CGRect può avere larghezza o altezza negative , dovremmo usare CGRectGetWidth()e CGRectGetHeight()invece di accedere direttamente al sizecampo nel rettangolo. Non credo che sia mai un problema rispetto al rettangolo dello schermo, ma suppongo che sia qualcosa di cui essere consapevoli.
Caleb,

64

Attento, [UIScreen mainScreen] contiene anche la barra di stato, se si desidera recuperare il frame per l'applicazione (esclusa la barra di stato) è necessario utilizzare

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

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}

4
deprecato in iOS 9.0
Zakaria Darwish,

6
poiché applicationFrame è obsoleto, sostituiscilo conreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81 il

44

Ho tradotto alcune delle precedenti risposte Objective-C in codice Swift. Ogni traduzione è seguita da un riferimento alla risposta originale.

Risposta principale

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

Risposta semplice funzione

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

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

Risposta orientamento 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
}

Registro risposta

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")

Sembra che ci sia un refuso nella risposta al registro: dovrebbe essere UIScreen.mainScreen (). Bounds.size.width? Ottengo un errore di compilazione senza ".bounds".
pietra,

@skypecakes Ho corretto la risposta per includere ".bounds". Grazie per il feedback.
Martin Woolstenhulme,

applicationFrame è obsoleto in iOS 9 e versioni successive, sostituirlo conreturn UIScreen.mainScreen().bounds].size.width
Suhaib

39

Ho usato questi metodi di convenienza prima:

- (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;
} 

Bella soluzione, ma fai attenzione che la temperatura sembra avere un'origine indefinita.
szemian,

4
Ottieni 0,0 come impostazione predefinita? Quando ho registrato fullScreenRect, mi ha dato: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Ho scelto di inizializzare con CGRect temp = CGRectZero;
szemian il

1
UIInterfaceOrientationIsL landscape non gestisce "UIDeviceOrientationFaceUp" e "UIDeviceOrientationFaceDown" che possono essere restituiti da UIDevice.
Andriy,

6
Potresti utilizzare la proprietà screen.applicationFrame invece di screen.bounds che si occupa della barra di stato.
Geraud.ch,

Risulta in alcuni casi applicationFrame non restituisce il frame con una barra di stato sottratta correttamente (modali a schermo intero da una splitview)
Luke Mcneice

15

Mi rendo conto che questo è un vecchio post, ma a volte trovo utile #define costanti come queste, quindi non devo preoccuparmene:

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

La costante di cui sopra dovrebbe restituire la dimensione corretta indipendentemente dall'orientamento del dispositivo. Quindi ottenere le dimensioni è semplice come:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;

Potresti voler basare la macro sulla risposta di AnswerBot poiché sembra la risposta migliore.
griotspeak

13

È molto, molto semplice ottenere le dimensioni del dispositivo e tenere conto dell'orientamento:

// 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];

Salve, lo uso in viewDidLoad su un'app solo per iPad orizzontale, c'è qualche motivo per cui ottiene il valore corretto per la prima volta, quindi il valore 'ribalta' su ogni carico dopo, ovvero lo legge come prima vista lanscape, quindi io vai via e torna alla vista e sembra leggerlo come ritratto anche se non è stata apportata alcuna modifica all'orientamento? Grazie
Craigk

@LukeMcneice Nel mio codice di produzione ho un'asserzione per assicurarmi che venga trovato un frame ... Devo ancora far fallire quell'asserzione. Cosa viene restituito per rootView e originalFrame?
Memmons,

Sto usando questa tecnica in un singleton per ottenere la larghezza / altezza corretta dall'orientamento. Tuttavia, se questo codice viene eseguito mentre una finestra UIAlert che mostra convertRect restituisce adjustedFrame con una dimensione (larghezza almeno) di 0. Qualche idea su cosa sta succedendo?
Electro-Bunny,

Ah. Un UIAlertViewsi inserirà come vista rootViewController della keyWindow. Ho una logica che evita il caso angolare perché se una vista di avviso è attiva, l'utente non può interagire con la tastiera, quindi in genere non è necessario afferrare la cornice della tastiera in quel momento.
Memmons

Grazie per la comprensione. Stavo usando la tua tecnica in un banner pubblicitario singleton. È stato un modo semplice e piacevole per dire all'annuncio la dimensione della cornice dello schermo per un nuovo annuncio. Dal momento che non sarò in grado di escludere a vicenda i banner pubblicitari e quelli di UIAlert, probabilmente ripiegherò sul rilevamento del paesaggio rispetto al ritratto e alla forza bruta cambiando x / y se necessario.
Electro-Bunny,

9

Dobbiamo considerare anche l'orientamento 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;
}

Buona soluzione ho fatto questo per far funzionare la mia app per iPad in orizzontale dall'interno di un controller di visualizzazione incorporato quando presentavo un VC modale.
StackRunner,

8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);

5

Qui ho aggiornato per Swift 3

applicationFrame deprecato da iOS 9

In tre rapidi hanno rimosso () e hanno modificato alcune convenzioni di denominazione, è possibile fare riferimento qui Link

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

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

4

La risposta moderna:

se la tua app supporta la visualizzazione divisa su iPad, questo problema diventa un po 'complicato. Sono necessarie le dimensioni della finestra, non quelle dello schermo, che possono contenere 2 app. Le dimensioni della finestra possono anche variare durante l'esecuzione.

Usa le dimensioni della finestra principale dell'app:

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

Nota: il metodo sopra riportato potrebbe avere un valore errato prima che la finestra diventi una finestra chiave all'avvio. se hai solo bisogno di larghezza, il metodo seguente è molto raccomandato :

UIApplication.shared.statusBarFrame.width

La vecchia soluzione che utilizza UIScreen.main.boundsrestituirà i limiti del dispositivo. Se la tua app funziona in modalità di visualizzazione divisa, ottiene dimensioni errate.

self.view.window nella risposta più calda potrebbe avere dimensioni errate quando l'app contiene 2 o più finestre e la finestra ha dimensioni ridotte.


4

Utilizzali Structsper conoscere informazioni utili sul dispositivo corrente in 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)

}

3

Se si desidera la larghezza / altezza dello schermo indipendentemente dall'orientamento del dispositivo (buono per dimensionare solo i controller di visualizzazione verticale lanciati da orientamenti orizzontali):

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

[UIScreen mainScreen] .nativeBounds <- Dai documenti -> Il rettangolo di delimitazione dello schermo fisico, misurato in pixel. Questo rettangolo si basa sul dispositivo con orientamento verticale. Questo valore non cambia quando il dispositivo ruota.


2

Ecco un modo rapido per ottenere le dimensioni dello schermo:

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
}

Questi sono inclusi come funzione standard in:

https://github.com/goktugyil/EZSwiftExtensions


1

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


1

veloce 3.0

per larghezza

UIScreen.main.bounds.size.width

per altezza

UIScreen.main.bounds.size.height

-2

Puoi posizionare queste macro nel tuo file pch e utilizzarle ovunque nel progetto 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)

Esempio di utilizzo:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;

Puoi indentare il codice secondo il formato markdown? Attualmente questo è stato contrassegnato come "bassa qualità" dagli utenti della comunità nella coda di revisione.
Manoj Kumar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.