Wie erhalte ich die Bildschirmbreite und -höhe in iOS?

506

Wie kann man die Abmessungen des Bildschirms in iOS erhalten?

Derzeit benutze ich:

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

in viewWillAppear:undwillAnimateRotationToInterfaceOrientation:duration:

Das erste Mal bekomme ich die gesamte Bildschirmgröße. Das zweite Mal bekomme ich den Bildschirm ohne die Navigationsleiste.

Griotspeak
quelle

Antworten:

1063

Wie kann man die Abmessungen des Bildschirms in iOS erhalten?

Das Problem mit dem von Ihnen geposteten Code besteht darin, dass Sie auf die Ansichtsgröße zählen, die der des Bildschirms entspricht, und wie Sie gesehen haben, ist dies nicht immer der Fall. Wenn Sie die Bildschirmgröße benötigen, sollten Sie sich das Objekt ansehen, das den Bildschirm selbst darstellt:

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

Update für geteilte Ansicht: In Kommentaren fragte Dmitry:

Wie kann ich die Größe des Bildschirms in der geteilten Ansicht ermitteln?

Der oben angegebene Code gibt die Größe des Bildschirms an, auch im geteilten Bildschirmmodus. Wenn Sie den geteilten Bildschirmmodus verwenden, ändert sich das Fenster Ihrer App. Wenn der obige Code nicht die erwarteten Informationen enthält, sehen Sie wie beim OP das falsche Objekt. In diesem Fall sollten Sie jedoch das Fenster anstelle des Bildschirms wie folgt betrachten:

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
quelle
7
Die Ausrichtung wird wirklich auf der Ebene des Ansichtscontrollers verwaltet. Sehen Sie sich die Verwaltung der Schnittstellenausrichtung eines View Controllers an . Schauen Sie sich also die Eigenschaft interfaceOrientation Ihres View Controllers an. Übrigens, Sie haben nach der Bildschirmgröße gefragt, also habe ich Ihnen das gezeigt, aber für die Anzeige Ihres Inhalts sollten Sie wahrscheinlich die Fenstergrenzen oder den Anwendungsrahmen des Bildschirms verwenden, je nachdem, was Sie tun.
Caleb
2
Es ist nützlich zu beachten, dass dies die volle Bildschirmbreite ohne Auffüllen zurückgibt . Subtrahieren Sie einfach die Polsterung Ihrer App (normalerweise 20 auf jeder Seite) von diesen Ergebnissen, um den "nutzbaren" Platz für die meisten Elemente zu erhalten
Nick Daugherty
2
@NickDaugherty Ja, das ist der Punkt - das OP wollte die Bildschirmabmessungen. Wo Sie Objekte auf dem Bildschirm platzieren, liegt ganz bei Ihnen und hängt davon ab, welche Art von App Sie erstellen. Wenn Sie beispielsweise ein Foto oder eine Spieloberfläche anzeigen, möchten Sie möglicherweise überhaupt keine Polsterung.
Caleb
3
Beachten Sie jedoch, dass dies einen in Punkten gemessenen Wert zurückgibt. Wenn Sie also die Bildschirmauflösung in Pixel erwarten würden, wäre das Ergebnis falsch, und Sie sollten das Ergebnis mit multiplizieren [UIScreen scale].
Robotbugs
3
Jemand wies darauf hin, dass wir , da ein CGRect eine negative Breite oder Höhe haben kann , das Feld im Rechteck verwenden CGRectGetWidth()und CGRectGetHeight()nicht direkt darauf zugreifen sollten size. Ich denke nicht, dass es jemals ein Problem in Bezug auf das Bildschirmrechteck sein wird, aber ich nehme an, dass es etwas ist, das man beachten sollte.
Caleb
64

Achtung, [UIScreen mainScreen] enthält auch die Statusleiste. Wenn Sie den Rahmen für Ihre Anwendung abrufen möchten (ohne Statusleiste), sollten Sie ihn verwenden

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

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}
Ege Akpinar
quelle
4
veraltet in ios 9.0
Zakaria Darwish
6
da applicationFrame veraltet ist, ersetzen Sie durchreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81
44

Ich habe einige der oben genannten Objective-C-Antworten in Swift-Code übersetzt. Jede Übersetzung wird mit einem Verweis auf die ursprüngliche Antwort fortgesetzt.

Hauptantwort

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

Einfache Funktionsantwort

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

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

Antwort zur Geräteorientierung

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
}

Antwort protokollieren

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")
Martin Woolstenhulme
quelle
Es scheint, als ob das Protokoll einen Tippfehler enthält. Antwort: Sollte es UIScreen.mainScreen (). Bounds.size.width sein? Ich erhalte einen Kompilierungsfehler ohne die ".bounds".
Stein
@skypecakes Ich habe die Antwort so korrigiert, dass sie ".bounds" enthält. Danke für die Rückmeldung.
Martin Woolstenhulme
applicationFrame ist in iOS 9 und höher veraltet. Ersetzen Sie es durchreturn UIScreen.mainScreen().bounds].size.width
Suhaib
39

Ich habe diese praktischen Methoden bereits verwendet:

- (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
quelle
Gute Lösung, aber seien Sie vorsichtig, dass die Temperatur einen undefinierten Ursprung zu haben scheint.
Szemian
4
Erhalten Sie standardmäßig 0,0? Als ich das fullScreenRect protokollierte, gab es mir Folgendes: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Ich habe mich für die Initialisierung mit CGRect temp = CGRectZero entschieden.
Szemian
1
UIInterfaceOrientationIsLandscape verarbeitet nicht 'UIDeviceOrientationFaceUp' und 'UIDeviceOrientationFaceDown', die möglicherweise von UIDevice zurückgegeben werden.
Andriy
6
Möglicherweise möchten Sie die Eigenschaft screen.applicationFrame anstelle von screen.bounds verwenden, die sich um die Statusleiste kümmert.
Geraud.ch
In einigen Fällen stellt sich heraus, dass applicationFrame kein Frame mit einer korrekt subtrahierten Statusleiste zurückgibt (Vollbildmodale aus einer geteilten Ansicht)
Luke Mcneice,
15

Mir ist klar, dass dies ein alter Beitrag ist, aber manchmal finde ich es nützlich, Konstanten wie diese zu definieren, damit ich mir darüber keine Sorgen machen muss:

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

Die obige Konstante sollte unabhängig von der Ausrichtung des Geräts die richtige Größe zurückgeben. Dann ist das Abrufen der Abmessungen so einfach wie:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;
Ein zufälliger Benutzer
quelle
Möglicherweise möchten Sie das Makro auf die Antwort von AnswerBot stützen, da dies die beste Antwort zu sein scheint.
Griotspeak
13

Es ist sehr, sehr einfach Ihr Gerät Größe zu erhalten sowie Berücksichtigung der Orientierung:

// 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
quelle
Hallo, ich verwende dies in viewDidLoad auf einer iPad-Landschafts-App. Gibt es einen Grund, warum es beim ersten Mal den richtigen Wert erhält, dann wird der Wert bei jedem Ladevorgang "umgedreht", dh es wird als lanscape first view gelesen, dann ich Navigieren Sie weg und zurück zur Ansicht und es scheint sie als Porträt zu lesen, obwohl keine Orientierungsänderung vorgenommen wurde. Danke
craigk
@LukeMcneice In meinem Produktionscode habe ich eine Zusicherung, um sicherzustellen, dass ein Frame gefunden wird ... Diese Zusicherung muss noch fehlschlagen. Was wird für rootView und originalFrame zurückgegeben?
Memmons
Ich verwende diese Technik in einem Singleton, um die orientierungskorrigierte Breite / Höhe zu erhalten. Wenn dieser Code jedoch ausgeführt wird, während ein UIAlert-Fenster, in dem convertRect angezeigt wird, adjustedFrame mit einer Größe (mindestens Breite) von 0 zurückgibt. Überlegen Sie, was damit los ist?
Electro-Bunny
Ah. An UIAlertViewfügt sich als rootViewController-Ansicht des keyWindow ein. Ich habe eine Logik, die den Eckfall vermeidet, da der Benutzer bei aktivierter Alarmansicht nicht mit der Tastatur interagieren kann, sodass zu diesem Zeitpunkt normalerweise kein Tastaturrahmen erforderlich ist.
Memmons
Danke für den Einblick. Ich habe Ihre Technik in einem Werbebanner-Singleton verwendet. Es war eine einfache und nette Möglichkeit, der Anzeigen-API die Größe des Bildschirmrahmens für eine neue Anzeige mitzuteilen. Da ich Bannerwerbung und UIAlert nicht gegenseitig ausschließen kann, werde ich wahrscheinlich bei Bedarf auf die Erkennung von Landschafts- und Hochformat- und Brute-Force-Umschaltungen x / y zurückgreifen.
Electro-Bunny
9

Wir müssen auch die Ausrichtung des Geräts berücksichtigen:

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
quelle
Gute Lösung Ich habe dies getan, um meine iPad-App in einem eingebetteten Ansichts-Controller im Querformat zum Laufen zu bringen, wenn eine modale VC präsentiert wird.
StackRunner
8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);
Gaurav Gilani
quelle
5

Hier habe ich für Swift 3 aktualisiert

applicationFrame ist von iOS 9 veraltet

In schnell drei haben sie entfernt () und sie haben einige Namenskonventionen geändert, Sie können hier Link verweisen

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

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

Die moderne Antwort:

Wenn Ihre App die geteilte Ansicht auf dem iPad unterstützt, wird dieses Problem etwas kompliziert. Sie benötigen die Fenstergröße, nicht die des Bildschirms, der 2 Apps enthalten kann. Die Größe des Fensters kann auch während des Betriebs variieren.

Verwenden Sie die Größe des Hauptfensters der App:

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

Hinweis: Die oben beschriebene Methode kann einen falschen Wert erhalten, bevor das Fenster beim Start zum Schlüsselfenster wird. Wenn Sie nur Breite benötigen, wird die folgende Methode sehr empfohlen :

UIApplication.shared.statusBarFrame.width

Die alte Lösung verwendet UIScreen.main.boundsdie Grenzen des Geräts zurück. Wenn Ihre App im geteilten Ansichtsmodus ausgeführt wird, werden die falschen Abmessungen angezeigt.

self.view.window In der heißesten Antwort kann die Größe falsch sein, wenn die App 2 oder mehr Fenster enthält und das Fenster klein ist.

Leavez
quelle
4

Nutzen Sie diese Structs, um nützliche Informationen zum aktuellen Gerät in Swift 3.0 zu erhalten

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
quelle
3

Wenn Sie die Bildschirmbreite / -höhe unabhängig von der Geräteausrichtung wünschen (nur für die Größenanpassung im Hochformat geeignet), werden Controller im Querformat gestartet:

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

[UIScreen mainScreen] .nativeBounds <- Aus den Dokumenten -> Das Begrenzungsrechteck des physischen Bildschirms, gemessen in Pixel. Dieses Rechteck basiert auf dem Gerät im Hochformat. Dieser Wert ändert sich nicht, wenn sich das Gerät dreht.

John Erck
quelle
2

Hier ist ein schneller Weg, um Bildschirmgrößen zu erhalten:

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
}

Diese sind standardmäßig enthalten in:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
quelle
1

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

Himanshu Jamnani
quelle
1

schnell 3.0

für die Breite

UIScreen.main.bounds.size.width

Für höhe

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

Sie können diese Makros in Ihre PCH-Datei einfügen und mit "SCREEN_WIDTH" an einer beliebigen Stelle im Projekt verwenden.

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

und "SCREEN_HEIGHT"

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

Anwendungsbeispiel:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;
Anny
quelle
Können Sie bitte Ihren Code gemäß dem Markdown-Format einrücken? Derzeit wurde dies von Community-Benutzern in der Überprüfungswarteschlange als "niedrige Qualität" gekennzeichnet.
Manoj Kumar