Wie erkenne ich das iPhone 5 (Breitbildgeräte)?

300

Ich habe gerade ein Upgrade auf XCode 4.5 GM durchgeführt und festgestellt, dass Sie jetzt die Größe "4" Retina "auf Ihren View Controller im Storyboard anwenden können.

Wenn ich jetzt eine Anwendung erstellen möchte, die sowohl auf dem iPhone 4 als auch auf dem iPhone 5 ausgeführt wird, muss ich natürlich jedes Fenster zweimal erstellen, aber ich muss auch erkennen, ob der Benutzer ein iPhone mit 3,5 "oder 4" Bildschirm hat, und dann das anwenden Aussicht.

Wie soll ich das machen

Finn Gaida
quelle
2
Sie müssen nicht jedes "Fenster" zweimal erstellen. Nur diejenigen, die genau der Bildschirmgröße entsprechen sollen, müssen weitergeleitet werden. Die Lösung liegt auf der Hand. Überprüfen Sie einfach die Fensterabmessungen und fügen Sie eine Fallentscheidung basierend auf der zurückgegebenen Größe hinzu.
Bis zum
1
Nun, im Grunde stimmt das, aber ich möchte die zusätzliche Bildschirmgröße auf eine ganz andere Art und Weise verwenden, wie Sie es mit einem Querformatbildschirm tun könnten.
Finn Gaida
Überprüfen Sie diese URL: stackoverflow.com/questions/4779221/…
ios_av
Sollte diese Frage entsprechend neuen Geräten aktualisiert werden? ZB "Wie erkennt man ein iOS-Gerät anhand der Bildschirmgröße?"
Hfossli
Überprüfen Sie diese github.com/aleemrazzaq/ARCompactDeviceInfo
Aleem

Antworten:

467

Zunächst sollten Sie nicht alle Ihre Ansichten neu erstellen, um sie an einen neuen Bildschirm anzupassen, und auch keine unterschiedlichen Ansichten für unterschiedliche Bildschirmgrößen verwenden.

Verwenden Sie die automatischen Größenänderung von iOS, damit Ihre Ansichten angepasst und jede Bildschirmgröße angepasst werden kann.

Das ist nicht sehr schwer zu lesen einige Dokumentationen darüber. Das spart Ihnen viel Zeit.

iOS 6 bietet dazu auch neue Funktionen.
Lesen Sie unbedingt das iOS 6 API-Änderungsprotokoll auf der Apple Developer-Website.
Und überprüfen Sie das neue iOS 6 AutoLayout Funktionen für .

Wenn Sie das iPhone 5 jedoch wirklich erkennen müssen, können Sie sich einfach auf die Bildschirmgröße verlassen .

[ [ UIScreen mainScreen ] bounds ].size.height

Der Bildschirm des iPhone 5 hat eine Höhe von 568.
Sie können sich ein Makro vorstellen, um all dies zu vereinfachen:

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

Die Verwendung von fabs mit dem Epsilon dient dazu, Präzisionsfehler beim Vergleich von Gleitkommawerten zu vermeiden, wie in den Kommentaren von H2CO3 angegeben.

Von nun an können Sie es in Standard-if / else-Anweisungen verwenden:

if( IS_IPHONE_5 )
{}
else
{}

Bearbeiten - Bessere Erkennung

Wie von einigen Leuten angegeben, tut dies nur einen Breitbildschirm , kein tatsächliches iPhone 5.

Die nächsten Versionen des iPod touch verfügen möglicherweise auch über einen solchen Bildschirm, sodass wir möglicherweise andere Makros verwenden.

Benennen wir das ursprüngliche Makro um IS_WIDESCREEN:

#define IS_WIDESCREEN ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

Und lassen Sie uns Modellerkennungsmakros hinzufügen:

#define IS_IPHONE ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPhone" ] )
#define IS_IPOD   ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPod touch" ] )

Auf diese Weise können wir sicherstellen, dass wir ein iPhone-Modell UND einen Breitbildmodus haben, und wir können das IS_IPHONE_5Makro neu definieren :

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Beachten Sie auch, dass diese Makros, wie von @ LearnCocos2D angegeben, nicht funktionieren, wenn die Anwendung nicht für den iPhone 5-Bildschirm optimiert ist (ohne das Bild [email protected]), da die Bildschirmgröße in solchen Fällen immer noch 320 x 480 beträgt ein Fall.

Ich denke nicht, dass dies ein Problem sein könnte, da ich nicht verstehe, warum wir ein iPhone 5 in einer nicht optimierten App erkennen möchten.

WICHTIG - iOS 8-Unterstützung

Unter iOS 8 spiegelt die boundsEigenschaft der UIScreenKlasse jetzt die Geräteorientierung wider .
Der vorherige Code funktioniert also offensichtlich nicht sofort.

Um dies zu beheben, können Sie nativeBoundsstattdessen einfach die neue Eigenschaft verwenden bounds, da sie sich nicht mit der Ausrichtung ändert und auf einem Hochformat basiert.
Beachten Sie, dass die Abmessungen von nativeBoundsin Pixel gemessen werden. Für ein iPhone 5 beträgt die Höhe 1136 statt 568.

Wenn Sie auch auf iOS 7 oder niedriger abzielen, stellen Sie sicher, dass Sie die Funktionserkennung verwenden, da Anrufe nativeBoundsvor iOS 8 Ihre App zum Absturz bringen:

if( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] )
{
    /* Detect using nativeBounds - iOS 8 and greater */
}
else
{
    /* Detect using bounds - iOS 7 and lower */
}

Sie können die vorherigen Makros folgendermaßen anpassen:

#define IS_WIDESCREEN_IOS7 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define IS_WIDESCREEN_IOS8 ( fabs( ( double )[ [ UIScreen mainScreen ] nativeBounds ].size.height - ( double )1136 ) < DBL_EPSILON )
#define IS_WIDESCREEN      ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_WIDESCREEN_IOS8 : IS_WIDESCREEN_IOS7 )

Wenn Sie ein iPhone 6 oder 6 Plus erkennen müssen, verwenden Sie natürlich die entsprechenden Bildschirmgrößen.

Macmade
quelle
7
Dies ist falsch, müssen Sie verwenden#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser
28
@ H2CO3: Beachten Sie, dass der Vergleich mit DBL_EPSILONhier nicht erforderlich ist und dass der ==Vergleich nicht fehlschlägt: Ein Vergleich mit Differenzen auf diese Weise ist nur erforderlich, wenn der Gleitkommawert nicht als exakte Zahl ausgedrückt werden kann (wie 1.0/3.0*3.0zum Beispiel). Lesen Sie diesen Artikel für weitere Informationen;)
AliSoftware
2
Diese Antwort ist nicht korrekt. Warum hat es so viele Daumen hoch bekommen? Sie können nicht nur die Höhe verwenden, um festzustellen, ob es sich um einen Breitbildmodus handelt. Alter ...
OMGPOP
5
Darf ich hinzufügen: Wenn dies mit dem Simulator funktionieren soll, verwenden Sie Folgendes: #define IS_IPHONE (([[UIDevice currentDevice] -Modell] isEqualToString: @ "iPhone"]) || ([[UIDevice currentDevice] -Modell] isEqualToString: @ "iPhone Simulator"]))
David
31
Diese Antwort ist Wahnsinn. Dieses Zeug über die Empfehlung, diese bestimmte Art von Floats (die in Wirklichkeit - und wenn Sie wissen, dass Apple wissen sollte, dass es immer - ganze Zahlen sind) nicht mit == zu vergleichen, ist Unsinn und überkompliziert die Dinge. Ich denke auch, dass es besser ist, UI_USER_INTERFACE_IDIOM () für die iPhone-Erkennung zu verwenden, da es sowohl auf dem Gerät als auch im Simulator einwandfrei funktioniert (und möglicherweise schneller als der UIDevice-Ansatz ist). Dies funktioniert einwandfrei und ist viel einfacher zu lesen: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez
232

Getestet und entwickelt für jede Kombination von SDK und Betriebssystem:

Schnell

IPad-Typen hinzugefügt. iPad 2 und iPad mini sind iPads ohne Netzhaut. Während iPad Mini 2 und höher, haben iPad 3, 4, iPad Air, Air 2, Air 3 und iPad Pro 9.7 dieselbe logische Auflösung von 1024. iPad Pro hat eine maximale Länge von 1366. Referenz

import UIKit

public enum DisplayType {
    case unknown
    case iphone4
    case iphone5
    case iphone6
    case iphone6plus
    case iPadNonRetina
    case iPad
    case iPadProBig
    static let iphone7 = iphone6
    static let iphone7plus = iphone6plus
}

public final class Display {
    class var width:CGFloat { return UIScreen.main.bounds.size.width }
    class var height:CGFloat { return UIScreen.main.bounds.size.height }
    class var maxLength:CGFloat { return max(width, height) }
    class var minLength:CGFloat { return min(width, height) }
    class var zoomed:Bool { return UIScreen.main.nativeScale >= UIScreen.main.scale }
    class var retina:Bool { return UIScreen.main.scale >= 2.0 }
    class var phone:Bool { return UIDevice.current.userInterfaceIdiom == .phone }
    class var pad:Bool { return UIDevice.current.userInterfaceIdiom == .pad }
    class var carplay:Bool { return UIDevice.current.userInterfaceIdiom == .carPlay }
    class var tv:Bool { return UIDevice.current.userInterfaceIdiom == .tv }
    class var typeIsLike:DisplayType {
        if phone && maxLength < 568 {
            return .iphone4
        }
        else if phone && maxLength == 568 {
                return .iphone5
        }
        else if phone && maxLength == 667 {
            return .iphone6
        }
        else if phone && maxLength == 736 {
            return .iphone6plus
        }
        else if pad && !retina {
            return .iPadNonRetina
        }
        else if pad && retina && maxLength == 1024 {
            return .iPad
        }
        else if pad && maxLength == 1366 {
            return .iPadProBig
        }
        return .unknown
    }
}

Sehen Sie es in Aktion https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Hinweis: Wenn sich z. B. das iPhone 6 im gezoomten Modus befindet, ist die Benutzeroberfläche eine vergrößerte Version des iPhone 5. Diese Funktionen bestimmen nicht den Gerätetyp, sondern den Anzeigemodus. Daher ist das iPhone 5 in diesem Beispiel das gewünschte Ergebnis.

Ziel c

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)

#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define IS_ZOOMED (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

#define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

Verwendung: http://pastie.org/9687735

Hinweis: Wenn sich z. B. das iPhone 6 im gezoomten Modus befindet, ist die Benutzeroberfläche eine vergrößerte Version des iPhone 5. Diese Funktionen bestimmen nicht den Gerätetyp, sondern den Anzeigemodus. Daher ist das iPhone 5 in diesem Beispiel das gewünschte Ergebnis.

hfossli
quelle
1
Das iPhone 5 meldet eine normale Bildschirmgröße von 480 x 320 ohne das neue Standardbild. Für mich ist das erwünschtes Verhalten.
Hfossli
3
Eine möglicherweise nützliche Ergänzung ist, #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)die helfen wird, den Unterschied zwischen iPhone4 und iPhone5 und iPad Retina und Nicht-Retina zu
bestimmen
1
Ich bin nicht einverstanden. Ich denke, die 'Widescreen'-Terminologie sollte weggelassen werden, da sie schnell veraltet ist.
Hfossli
1
@Dvole So verhält sich iOS 8. Verwenden Sie SCREEN_MAX_LENGTH, um 568 in allen Umdrehungen auf dem iPhone 5 zu erhalten.
hfossli
1
@MattParkins Ich würde vorschlagen, robustere Modellprüfungen zu verwenden . Stackoverflow.com/questions/13366976/… .
Hfossli
69

Wirklich einfache Lösung

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}
Samrat Mazumdar
quelle
1
haha kurz und simpel, habe das gleiche gemacht :) pocht hoch, um den Overhead niedrig zu halten! Sachen in ein Makro zu setzen ist keine Herausforderung ...
benjamin.ludwig
2
Nun, Dinge nicht in Makros oder Funktionen zu setzen, neigt dazu, nicht
trocken
Ja, aber Makro wie oben gezeigt zu definieren, ist bequemer und einfacher. Sie müssen dies nicht einfügen, wenn ... jedes Mal.
Ruhig
Danke, Sie haben mir das Leben gerettet: D, aber ich weiß nicht, warum Makro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds] .size.height == 568.0) ==> Funktioniert vorher nicht in Simulator iOS 7.1 dass ich noch an XCode 4.6 arbeite. OMG iOS 7.1 & Xcode 5
Linh Nguyen
aktualisierte Antwort unten, um iPhone 6 und 6 plus Bildschirmgrößen zu berücksichtigen
Sam B
28

Wir müssen jetzt die Bildschirmgrößen für iPhone 6 und 6Plus berücksichtigen. Hier ist eine aktualisierte Antwort

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    //its iPhone. Find out which one?

    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    else if(result.height == 568)
    {
        // iPhone 5
    }
    else if(result.height == 667)
    {
        // iPhone 6
    }
   else if(result.height == 736)
    {
        // iPhone 6 Plus
    }
}
else
{
     //its iPad
}

Einige nützliche Informationen

iPhone 6 Plus   736x414 points  2208x1242 pixels    3x scale    1920x1080 physical pixels   401 physical ppi    5.5"
iPhone 6        667x375 points  1334x750 pixels     2x scale    1334x750 physical pixels    326 physical ppi    4.7"
iPhone 5        568x320 points  1136x640 pixels     2x scale    1136x640 physical pixels    326 physical ppi    4.0"
iPhone 4        480x320 points  960x640 pixels      2x scale    960x640 physical pixels     326 physical ppi    3.5"
iPhone 3GS      480x320 points  480x320 pixels      1x scale    480x320 physical pixels     163 physical ppi    3.5"
Sam B.
quelle
Es funktioniert einfach nicht für mich. iPhone 5 hat sich entschieden, da 4 iPhone 6+ überhaupt nicht entschieden hat. Oh, ich habe es verstanden. Ich bin in der Landschaft. Ich sollte die Höhe mit der Breite ändern. :)
ColdSteel
Wenn sich Ihre App im Querformat befindet, stellen Sie sicher, dass Sie result.height in result.width ändern
Sam B
hmm .. auf iPhone 4 (iOS 6.0) hat es nicht getauscht :( könnte iOS 6.0 prob oder ein iPhone 4 sein?
ColdSteel
Okay, ich habe die Ansicht überprüft, die nur in iOS 8 und höher
ausgetauscht wurde
iPhone 6 gibt Höhe = 568
MaxEcho
15

Ich habe mir die Freiheit genommen, das Makro von Macmade in eine C-Funktion zu setzen und es richtig zu benennen, da es die Breitbildverfügbarkeit erkennt und NICHT unbedingt das iPhone 5.

Das Makro erkennt auch nicht, dass es auf einem iPhone 5 ausgeführt wird, wenn das Projekt nicht die [email protected] enthält . Ohne das neue Standardbild meldet das iPhone 5 eine normale Bildschirmgröße von 480 x 320 (in Punkten). Die Überprüfung betrifft also nicht nur die Breitbildverfügbarkeit, sondern auch den aktivierten Breitbildmodus .

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}
LearnCocos2D
quelle
Ich bevorzuge aus Leistungsgründen immer noch die Makros. Bitte beachten Sie die Bearbeitung meiner Antwort. Es überprüft auch das Modell.
Macmade
1
Sie haben auch Recht, wenn Sie sagen, dass ein iPhone 5 eine normale Bildschirmgröße von 480 x 320 ohne das neue Standardbild anzeigt. Aber ich denke, es macht keinen Sinn, ein iPhone 5 in einer nicht optimierten App zu erkennen. :)
Macmade
@Macmade In der Tat macht es keinen Sinn, aber es ist gut zu bedenken, falls die Erkennung nicht funktioniert. Funktionen können auch inlined sein. Sie werden auch dort eingefügt, wo der Optimierer des Compilers dies für eine gute Idee hält und wo er wissen kann, dass dies zulässig ist (z. B. befindet sich die Funktion im selben Modul). Das Implementieren solcher Dinge über eine Funktion kann manchmal eine zusätzliche Typprüfung mit sich bringen.
Ivan Vučica
4
Die leistungsbezogene Frage lautet: Warum sollten Sie diese Prüfung während Ihrer Renderschleife tausende Male ausführen? Ansonsten ist Leistung kein Problem und Klarheit und Vermeidung von Nebenwirkungen von größerer Bedeutung.
LearnCocos2D
Ich habe Ihnen dafür eine +1 gegeben, weil mir die separate Funktion eher gefällt als ein Makro, aber ich muss darauf hinweisen, dass sie nicht wirklich korrekt oder vollständig ist. Um Breitbild zu erkennen, schauen Sie nicht auf die Höhe des Bildschirms. Schauen Sie sich stattdessen das Seitenverhältnis an und geben Sie nur dann true zurück, wenn das Seitenverhältnis größer oder gleich 16: 9 ist.
Todd Lehman
11

Hier sind unsere Codes, Test auf ios7 / ios8 für iphone4, iphone5, ipad, iphone6, iphone6p bestanden, egal auf Geräten oder Simulator:

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) // iPhone and       iPod touch style UI

#define IS_IPHONE_5_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 568.0f)

#define IS_IPHONE_5_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 568.0f)
#define IS_IPHONE_6_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 667.0f)
#define IS_IPHONE_6P_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) < 568.0f)

#define IS_IPHONE_5 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_5_IOS8 : IS_IPHONE_5_IOS7 )
#define IS_IPHONE_6 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6_IOS8 : IS_IPHONE_6_IOS7 )
#define IS_IPHONE_6P ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6P_IOS8 : IS_IPHONE_6P_IOS7 )
#define IS_IPHONE_4_AND_OLDER ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_4_AND_OLDER_IOS8 : IS_IPHONE_4_AND_OLDER_IOS7 )
Ingwer
quelle
Ich teste auf einem iPhone 6P und meine if-Anweisung fällt in den Zustand IS_IPHONE_5? Wie kann das sein, dein Code sieht gut aus? Ich habe ein direktes Kopieren und Einfügen mit einem einfachen if / else durchgeführt und ich weiß, dass mein Telefon eine 6 plus mit iOS 8.3 ist.
Whyoz
7

Ich habe die Antwort von hfossli verwendet und sie in Swift übersetzt

let IS_IPAD = UIDevice.currentDevice().userInterfaceIdiom == .Pad
let IS_IPHONE = UIDevice.currentDevice().userInterfaceIdiom == .Phone
let IS_RETINA = UIScreen.mainScreen().scale >= 2.0

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

let IS_IPHONE_4_OR_LESS = (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
let IS_IPHONE_5 = (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
let IS_IPHONE_6 = (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
let IS_IPHONE_6P = (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
Borbea
quelle
6

Dies ist das Makro für mein cocos2d-Projekt. sollte für andere Apps gleich sein.

#define WIDTH_IPAD 1024
#define WIDTH_IPHONE_5 568
#define WIDTH_IPHONE_4 480
#define HEIGHT_IPAD 768
#define HEIGHT_IPHONE 320

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

//width is height!
#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_5 )
#define IS_IPHONE_4 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_4 )

#define cp_ph4(__X__, __Y__) ccp(cx_ph4(__X__), cy_ph4(__Y__))
#define cx_ph4(__X__) (IS_IPAD ? (__X__ * WIDTH_IPAD / WIDTH_IPHONE_4) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPHONE_4) : (__X__)))
#define cy_ph4(__Y__) (IS_IPAD ? (__Y__ * HEIGHT_IPAD / HEIGHT_IPHONE) : (__Y__))

#define cp_pad(__X__, __Y__) ccp(cx_pad(__X__), cy_pad(__Y__))
#define cx_pad(__X__) (IS_IPAD ? (__X__) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPAD) : (__X__ * WIDTH_IPHONE_4 / WIDTH_IPAD)))
#define cy_pad(__Y__) (IS_IPAD ? (__Y__) : (__Y__ * HEIGHT_IPHONE / HEIGHT_IPAD))
OMGPOP
quelle
5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}
D-eptdeveloper
quelle
3

In Swift, iOS 8+ Projekt möchte ich eine Erweiterung machen UIScreen, wie:

extension UIScreen {

    var isPhone4: Bool {
        return self.nativeBounds.size.height == 960;
    }

    var isPhone5: Bool {
        return self.nativeBounds.size.height == 1136;
    }

    var isPhone6: Bool {
        return self.nativeBounds.size.height == 1334;
    }

    var isPhone6Plus: Bool {
        return self.nativeBounds.size.height == 2208;
    }

}

(HINWEIS: nativeBoundsist in Pixel).

Und dann lautet der Code wie folgt:

if UIScreen.mainScreen().isPhone4 {
    // do smth on the smallest screen
}

Der Code macht also deutlich, dass dies eine Überprüfung für den Hauptbildschirm ist, nicht für das Gerätemodell.

zubko
quelle
2

In Anlehnung an die Antwort von Samrat Mazumdar finden Sie hier eine kurze Methode, mit der die Bildschirmgröße des Geräts geschätzt wird. Es funktioniert mit den neuesten Geräten, kann jedoch bei zukünftigen Geräten fehlschlagen (wie bei allen Vermutungsmethoden). Es wird auch verwirrt, wenn das Gerät gespiegelt wird (gibt die Bildschirmgröße des Geräts zurück, nicht die gespiegelte Bildschirmgröße).

#define SCREEN_SIZE_IPHONE_CLASSIC 3.5
#define SCREEN_SIZE_IPHONE_TALL 4.0
#define SCREEN_SIZE_IPAD_CLASSIC 9.7

+ (CGFloat)screenPhysicalSize
{
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        if (result.height < 500)
            return SCREEN_SIZE_IPHONE_CLASSIC;  // iPhone 4S / 4th Gen iPod Touch or earlier
        else
            return SCREEN_SIZE_IPHONE_TALL;  // iPhone 5
    }
    else
    {
        return SCREEN_SIZE_IPAD_CLASSIC; // iPad
    }
} 
Jeff Hay
quelle
Benötigt eine Überarbeitung für das iPad mini, die Sie meines Erachtens in diesem Herrenhaus nicht feststellen können.
Daniel
Ja, das iPad mini hat die gleiche Auflösung wie das iPad2, daher funktioniert diese Methode nicht. Ich bin mir nicht sicher, wie ich mit diesem Fall umgehen soll ...
Jeff Hay
1
Das sollst du nicht. Sie können die Gerätekennung für "iPad 2,5" kaufen. Außerdem müssen Sie nach 2,6 und 2,7 suchen - der Nur-WLAN-Version, GSM und CDMA. Dies bedeutet jedoch, dass das nächste iPad mini veröffentlicht wird und Sie auf Hardcode aktualisieren müssen, um auch die Kennungen zu erhalten, die Sie vorher nicht kennen. Sie können nicht ständig wissen, wann Sie auf einem iPad mini sind, weil Sie wirklich nicht versuchen sollten, für den kleineren Bildschirm zu "optimieren"
Daniel
2

Ich denke, es sollte gut sein, wenn dieses Makro in Gerät und Simulator funktioniert, unten sind die Lösung.

#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString:@"iPhone"]) || ([[[UIDevice currentDevice] model] isEqualToString: @"iPhone Simulator"]))
#define IS_IPOD   ([[[UIDevice currentDevice]model] isEqualToString:@"iPod touch"])
#define IS_IPHONE_5 ((IS_IPHONE || IS_IPOD) && IS_WIDESCREEN)
Bhavesh Dhaduk
quelle
2

Ich habe festgestellt, dass die Antworten keinen Sonderfall für Simulatoren enthalten.

#define IS_WIDESCREEN ( [ [ UIScreen mainScreen ] bounds ].size.height == 568  )
#define IS_IPHONE ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPhone"].location != NSNotFound)
#define IS_IPAD ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPad"].location != NSNotFound)
#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )
Valvolin
quelle
2
+(BOOL)isDeviceiPhone5
{
    BOOL iPhone5 = FALSE;

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568)
    {
        // code for 4-inch screen
        iPhone5 = TRUE;
    }
    else
    {
        iPhone5 = FALSE;
        // code for 3.5-inch screen
    }
    return iPhone5;

}
Mubin Shaikh
quelle
iPhone5 = FALSE;ist unnötig, weil die Variable bereits diesen Wert hat, wenn sie nicht geändert wird
mcont
1
CGFloat height = [UIScreen mainScreen].bounds.size.height;

NSLog(@"screen soze is %f",height);

  if (height>550) {

          // 4" screen-do some thing
     }

  else if (height<500) {

        // 3.5 " screen- do some thing

     }
Nithin M Keloth
quelle
1

Sich auf die Größe zu verlassen ist in so vielen Ebenen falsch. Wie wäre es, wenn wir das System fragen?

- (NSString *) getDeviceModel
{
    struct utsname systemInfo;
    uname(&systemInfo);
    return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}

Entnommen aus dem besten Weg, um Hardwaretyp, iPhone4 oder iPhone5 zu erkennen? , edzio27 Antwort.

3d0
quelle
1

Auf diese Weise können Sie die Gerätefamilie erkennen.

    #import <sys/utsname.h>
    NSString* deviceName()
    {
        struct utsname systemInformation;
        uname(&systemInformation);
        NSString *result = [NSString stringWithCString:systemInformation.machine
                                              encoding:NSUTF8StringEncoding];
        return result;
    }

    #define isIPhone5  [deviceName() rangeOfString:@"iPhone5,"].location != NSNotFound
    #define isIPhone5S [deviceName() rangeOfString:@"iPhone6,"].location != NSNotFound
Xeieshan
quelle
1

Wenn das Projekt mit Xcode 6 erstellt wurde, verwenden Sie den unten angegebenen Code, um die Geräte zu erkennen.

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136){
            printf("Device Type : iPhone 5,5S/iPod 5 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1334){
            printf("Device Type : iPhone 6 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 2208){
            printf("Device Type : iPhone 6+ ");

        }
    }
}else{
    printf("Device Type : iPad");
}

Wenn das Projekt in Xcode 5 erstellt und in Xcode 6 geöffnet wurde, verwenden Sie den unten angegebenen Code, um die Geräte zu erkennen. (Dieser Code funktioniert, wenn keine Startbilder für das iPhone 6,6+ zugewiesen sind.)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
       if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s");
            appType=1;
        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136 || [[UIScreen mainScreen] nativeBounds].size.height == 1704){
            printf("Device Type : iPhone 5,5S,6,6S/iPod 5 ");
            appType=3;
        }
    }
}else{
    printf("Device Type : iPad");
    appType=2;
}

Wenn Sie immer noch Xcode 5 zusammen verwenden, verwenden Sie den folgenden Code, um die Geräte zu erkennen (iPhone 6 und 6+ werden nicht erkannt).

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] bounds].size.width,(int)[[UIScreen mainScreen] bounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        CGFloat scale = [UIScreen mainScreen].scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
        if(result.height == 960 || result.height == 480){
            printf("Device Type : iPhone 4,4S ");

        }else if(result.height == 1136){
            printf("Device Type : iPhone 5s/iPod 5");

        }
    }
}else{
    printf("Device Type : iPad");

}
Aritra Das
quelle
1
  1. Fügen Sie eine 'Neue Swift-Datei' hinzu -> AppDelegateEx.swift

  2. Fügen Sie eine Erweiterung hinzu AppDelegate

    import UIKit
    extension AppDelegate {
         class func isIPhone5 () -> Bool{
             return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 568.0
        }
        class func isIPhone6 () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 667.0
        }
        class func isIPhone6Plus () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 736.0
        }  
    }
  3. Verwendung:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }
William Hu
quelle
1

In Swift 3 können Sie meine einfache Klasse KRDeviceType verwenden.

https://github.com/ulian-onua/KRDeviceType

Es ist gut dokumentiert und unterstützt Operatoren ==,> =, <=.

Um beispielsweise festzustellen, ob das Gerät an iPhone 6 / 6s / 7 gebunden ist, können Sie einfach den nächsten Vergleich verwenden:

if KRDeviceType() == .iPhone6 {
// Perform appropiate operations
}

Um festzustellen, ob das Gerät an iPhone 5 / 5S / SE oder früher (iPhone 4s) gebunden ist, können Sie den nächsten Vergleich verwenden:

if KRDeviceType() <= .iPhone5 {   //iPhone 5/5s/SE of iPhone 4s
// Perform appropiate operations (for example, set up constraints for those old devices)
}
Julian D.
quelle
1

Dies wurde hundertmal beantwortet, aber diese Lösung hat für mich am besten funktioniert und dazu beigetragen, das Problem zu beheben, wenn neue Geräte eingeführt werden und ich keine Größe definiert habe.

Swift 5 Helfer:

extension UIScreen {
    func phoneSizeInInches() -> CGFloat {
        switch (self.nativeBounds.size.height) {
        case 960, 480:
            return 3.5  //iPhone 4
        case 1136:
            return 4    //iPhone 5
        case 1334:
            return 4.7  //iPhone 6
        case 2208:
            return 5.5  //iPhone 6 Plus
        case 2436:
            return 5.8  //iPhone X
        case 1792:
            return 5.5  //iPhone XR
        case 2688:
            return 6.5  //iPhone XS Max
        default:
            let scale = self.scale
            let ppi = scale * 163
            let width = self.bounds.size.width * scale
            let height = self.bounds.size.height * scale
            let horizontal = width / ppi, vertical = height / ppi
            let diagonal = sqrt(pow(horizontal, 2) + pow(vertical, 2))
            return diagonal
        }
    }
}

Dies liegt daran, dass es einfach ist, sich die Zollgrößen eines Telefons zu merken, z. B. "5,5 Zoll" oder "4,7 Zoll", aber es ist schwierig, sich die genauen Pixelgrößen zu merken.

if UIScreen.main.phoneSizeInInches() == 4 {
  //do something with only 4 inch iPhones
}

Dies gibt Ihnen auch die Möglichkeit, Folgendes zu tun:

if UIScreen.main.phoneSizeInInches() < 5.5 {
  //do something all iPhones smaller than the plus
}

Die Standardeinstellung: versucht, die Bildschirmgröße und -skalierung zu verwenden, um die diagonalen Zoll zu berechnen. Wenn eine neue Gerätegröße angezeigt wird, wird versucht, das Beste zu ermitteln, und der Code, wie im letzten Beispiel, sollte weiterhin funktionieren.

William T.
quelle
0

Verwenden Sie den folgenden Code:

CGFloat screenScale = [[UIScreen mainScreen] scale];

CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale); 

if (screenSize.height==1136.000000)
{ 
    // Here iPhone 5 View

    // Eg: Nextview~iPhone5.Xib
} else {
   // Previous Phones 

   // Eg : Nextview.xib
}
Laszlo
quelle
0

Hier ist der richtige Test des Gerätes, unabhängig von der Ausrichtung

- (BOOL)isIPhone5
{
    CGSize size = [[UIScreen mainScreen] bounds].size;
    if (MIN(size.width,size.height) == 320 && MAX(size.width,size.height == 568)) {
        return YES;
    }
    return NO;
}
Pawel Molodkin
quelle
-2

Wird verwendet, um iPhone- und iPad-Geräte aller Art zu erkennen.

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 
Vaibhav Sharma
quelle
iPhone 6 hat kein Retina-Display?
Vikingosegundo
Das iPhone6 ​​verfügt über das Ratina-Display (@ 2X). und das iPhone 6 plus verfügt über ein HD-Display (@ 3X).
Vaibhav Sharma
Wenn also IS_RETINAauf einem iPhone 6 plus getestet , wird 1x Code ausgeführt?
Vikingosegundo
Siehe diesen Link. stackoverflow.com/questions/25756589/…
Vaibhav Sharma
1
du verstehst es nicht: deine Regeln werden nachgeben @1x, wo sie nachgeben sollten @3x. sowieso: wie Sie einfach kopieren und
einfügen