2010-07-17 13 views
24

In meiner Anwendung lade ich einige Bilder aus dem Internet (von meinem Server um genau zu sein), um einige Bandbreite und vor allem Speicher auf dem Telefon zu speichern, stelle ich sie in zwei Auflösungen: 480x320 für die "alte" iPhone-Serie und in 960x640 für das iPhone 4 mit dem Retina-Display. Jetzt muss ich in der App erkennen können, wenn es auf einem Gerät läuft, das den Retina-Bildschirm unterstützt. Wie könnte ich das tun?Detect Retina Bildschirm/iPhone 4 in iPhone SDK

Ich habe über die Verwendung des Codeausschnitts nachgedacht, der mir eine spezifische Geräteidentifikation wie zB zurückgeben würde. "iPhone3", aber dann würde ich die Erkennung auf das iPhone4 beschränken und müsste diesen Code für jedes nachfolgende Gerät mit einer Retina-Anzeige aktualisieren.

size_t size; 

// Set 'oldp' parameter to NULL to get the size of the data 
// returned so we can allocate appropriate amount of space 
sysctlbyname("hw.machine", NULL, &size, NULL, 0); 

// Allocate the space to store name 
char *name = malloc(size); 

// Get the platform name 
sysctlbyname("hw.machine", name, &size, NULL, 0); 

// Place name into a string 
NSString *machine = [NSString stringWithCString:name]; 

Gibt es eine bessere soution (vielleicht ist es sehr offensichtlich, aber ich habe es verpasst)?

Antwort

32

Habe gerade etwas gelesen auf den offiziellen Apple Developers Foren und die Probleme wurden dort ausführlich diskutiert. Der beste Weg zu mir scheint die Verwendung der scale Eigenschaft von UIScreen zu sein. Obwohl es nur in iOS 4 und später verfügbar ist, wird es Ihnen alles erzählen, was Sie wissen müssen und wird wahrscheinlich eine noch wichtigere Rolle in der Zukunft spielen (schon bemerkt, dass die iPad Auflösung von 1024x768 genau 32/15 * 480x320 ist?).

UIScreen.mainScreen.scale 

Wenn Sie noch eine andere Idee fühlen Sie sich frei, es zu senden :)

+0

Dies ist der richtige Weg, es zu tun. – Elfred

+2

Ja, benutze das, versuche niemals zu fragen, auf welchem ​​Gerät du liegst, es wird nur mit Schmerzen enden. –

+0

Das ist der richtige Ansatz, da Sie keinen bedingten Code für das iPhone 4 schreiben möchten, sondern für eine Anzeige mit einer anderen Skalierung/Auflösung. Wer weiß, wann der iPod die Netzhautbehandlung bekommt. – FelixLam

1

Gehen Sie mit Robin Antwort. Ein weiterer Hinweis: Wenn Sie den Gerätenamen überprüfen müssen, verwenden Sie einfach die Methoden auf UIDevice.

[[UIDevice currentDevice] model]; 
[[UIDevice currentDevice] systemName]; 
[[UIDevice currentDevice] systemVersion]; 
+1

Übung für den Leser: Warum ist es immer eine schlechte Idee, das Gerät (statt der Fähigkeiten) zu erkennen? –

23

Hier ist ein Code es den richtigen Weg für beide iOS 3.x und 4.x zu tun:

BOOL hasHighResScreen = NO; 
if ([UIScreen instancesRespondToSelector:@selector(scale)]) { 
    CGFloat scale = [[UIScreen mainScreen] scale]; 
    if (scale > 1.0) { 
     hasHighResScreen = YES; 
    } 
} 
+0

Achten Sie darauf, dass dies auch für den "iphone simulator" -Modus des iPads gilt, wenn es mit 2x startet, was möglicherweise nicht Ihren Vorstellungen entspricht. –

+2

Gibt es eine Problemumgehung für das 2x-Problem auf dem "iphone simulator" des iPads? – joelsand

5

I get real Bildschirmgröße (in Pixeln) auf diese Weise:

UIScreen *MainScreen = [UIScreen mainScreen]; 
UIScreenMode *ScreenMode = [MainScreen currentMode]; 
CGSize Size = [ScreenMode size]; // <--- Real screen size 
1
UIScreen *MainScreen = [UIScreen mainScreen]; 
UIScreenMode *ScreenMode = [MainScreen currentMode]; 
CGSize Size = [ScreenMode size]; // <--- Real screen size 
0

Wenn Sie Cocos2d verwenden, versuchen Sie folgendes:

[[CCDirector sharedDirector] winSizeInPixels];

Es wird eine CGSize mit Eigenschaften width und height zurückzukehren.

15

Ein kleines Update auf Antwort von Scott Gustafson:

Wenn wir zwischen iPad/Retina/iphone unterscheiden müssen:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    { 
     CGFloat scale = [[UIScreen mainScreen] scale]; 

      if (scale > 1.0) 
      { 
       //iPad retina screen 
      } 
      else 
      { 
       //iPad screen 
      } 
    } 
    else 
    { 
     if ([UIScreen instancesRespondToSelector:@selector(scale)]) 
     { 
       CGFloat scale = [[UIScreen mainScreen] scale]; 

       if (scale > 1.0) 
       { 
        if([[ UIScreen mainScreen ] bounds ].size.height == 568) 
        { 
         //iphone 5 
        } 
        else 
        { 
         //iphone retina screen 
        } 
       } 
       else 
       { 
        //iphone screen 
       } 
     } 
    } 
-1

Obwohl Sie bereits eine Antwort ausgewählt haben, gibt es eine viel einfacher ist, wenn ich mich speziell mit Bildern beschäftige, werde ich es auch erwähnen.

Wenn Sie zwei Bilder in Ihr Bündel der zwei Größen (320x480 und 640x960) einfügen und am Ende des Dateinamens des zweiten Bildes "@ 2x" anhängen, wählt [UIImage imageNamed:] automatisch das kleinere Bild für älter aus Geräte und das 2x für Geräte mit Retina-Display, sofern Sie das Bild-Suffix weglassen. Bsp .:

2 Bilder namens @ "image.png" und @ "[email protected]", beide im App-Bundle enthalten.

rufen dann:

[UIImage imageNamed:@"image"]; 

Dies ist auch, wie App-Symbole und der Ladebildschirm zu arbeiten.

+0

-1: Hast du den Anfang des Posts nicht gelesen ...? Um zu zitieren: "In meiner Anwendung lade ich einige Bilder aus dem Internet herunter **" –

1

Und für diejenigen, die einfach kopieren/einfügen möchten, wie iphone/iphone_retina/ipad/ipad_retina zu erkennen, hier ist, was ich nach dem Lesen dieses Threads getan habe. Stark inspiriert von Guntis Treulands Beitrag, der seinerseits Scott Gustafsons Antwort erweiterte.

- (NSString *) yesButWhichDeviceIsIt {  
    BOOL hasRetina = NO; 
    if ([UIScreen instancesRespondToSelector:@selector(scale)]) { 
     CGFloat scale = [[UIScreen mainScreen] scale]; 
     if (scale > 1.0) { 
      hasRetina = YES; 
     } 
    } 
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
     if (hasRetina) { 
      return @"iPad retina"; 
     } else { 
      return @"iPad"; 
     } 
    } else { 
     if (hasRetina) { 
      return @"iPhone retina"; 
     } else { 
      return @"iPhone"; 
     }   
    } 
} 
0
+(BOOL)Retina{ 
     return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; } 
+2

Normale Kakao-Benennungspraxis würde vorschreiben, die Methode mit einem kleingeschriebenen Anfangsbuchstaben zu benennen. – Monolo

3
- (BOOL)isRetina { 

    BOOL isRetina = NO; 

    if ([UIScreen instancesRespondToSelector:@selector(scale)]) { 
     CGFloat scale = [[UIScreen mainScreen] scale]; 
     if (scale > 1.0) { 
      isRetina = YES; 
     } 
    } 

    return isRetina; 
} 


- (CGSize)sizeInPixels { 

    CGRect appFrame = [[UIScreen mainScreen] applicationFrame]; 
    CGSize screenSize = CGSizeMake(appFrame.size.width, appFrame.size.height); 

    return [self isRetina] ? CGSizeMake(screenSize.width * 2, screenSize.height * 2) : screenSize; 
}