Come rilevare iPhone 5 (dispositivi widescreen)?


300

Ho appena eseguito l'aggiornamento a XCode 4.5 GM e ho scoperto che ora puoi applicare la dimensione "4" Retina "al tuo controller di visualizzazione nello storyboard.

Ora, se voglio creare un'applicazione che funziona su iPhone 4 e 5, ovviamente devo costruire ogni finestra due volte, ma devo anche rilevare se l'utente ha un iPhone con schermo da 3,5 "o 4" e quindi applicare il Visualizza.

Come dovrei farlo?


2
Non devi costruire ogni "finestra" due volte. Solo quelli che dovrebbero corrispondere esattamente alle dimensioni dello schermo dovranno essere trasmessi. La soluzione sembra piuttosto ovvia, basta controllare le dimensioni della finestra e aggiungere una decisione sul caso in base alla dimensione restituita.
Fino al

1
Bene, fondamentalmente è vero, ma voglio usare le dimensioni extra dello schermo in un modo completamente diverso, come potresti fare con uno schermo orizzontale.
Finn Gaida,


Questa domanda dovrebbe essere aggiornata in conformità con i nuovi dispositivi? Ad esempio "Come rilevare il dispositivo iOS in base alle dimensioni dello schermo"?
hfossli,

Risposte:


467

Prima di tutto, non dovresti ricostruire tutte le tue viste per adattarle a un nuovo schermo, né usare viste diverse per schermi di dimensioni diverse.

Utilizza le funzionalità di ridimensionamento automatico di iOS, in modo che le tue visualizzazioni possano adattarsi e adattare qualsiasi dimensione dello schermo.

Non è molto difficile, leggi un po 'di documentazione a riguardo. Ti farà risparmiare un sacco di tempo.

iOS 6 offre anche nuove funzionalità al riguardo.
Assicurati di leggere il log delle modifiche dell'API iOS 6 sul sito Web degli sviluppatori Apple.
E controlla le nuove funzionalità di AutoLayout di iOS 6 .

Detto questo, se hai davvero bisogno di rilevare l'iPhone 5, puoi semplicemente fare affidamento sulle dimensioni dello schermo .

[ [ UIScreen mainScreen ] bounds ].size.height

Lo schermo dell'iPhone 5 ha un'altezza di 568.
Puoi immaginare una macro, per semplificare tutto questo:

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

L'uso di fabscon epsilon è qui per prevenire errori di precisione, quando si confrontano i punti fluttuanti, come sottolineato nei commenti di H2CO3.

Quindi d'ora in poi puoi usarlo nelle istruzioni if ​​/ else standard:

if( IS_IPHONE_5 )
{}
else
{}

Modifica: migliore rilevamento

Come affermato da alcune persone, questo rileva solo un widescreen , non un vero iPhone 5.

Le prossime versioni di iPod touch avranno forse anche uno schermo del genere, quindi potremmo usare un altro set di macro.

Rinominiamo la macro originale IS_WIDESCREEN:

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

E aggiungiamo le macro di rilevamento del modello:

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

In questo modo, possiamo assicurarci di avere un modello di iPhone E un widescreen e possiamo ridefinire la IS_IPHONE_5macro:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Inoltre, come affermato da @ LearnCocos2D, queste macro non funzioneranno se l'applicazione non è ottimizzata per lo schermo dell'iPhone 5 (manca l'immagine Default-568h@2x.png), poiché le dimensioni dello schermo saranno comunque 320x480 in tale un caso.

Non penso che questo possa essere un problema, in quanto non vedo perché vorremmo rilevare un iPhone 5 in un'app non ottimizzata.

IMPORTANTE: supporto per iOS 8

Su iOS 8, la boundsproprietà della UIScreenclasse ora riflette l' orientamento del dispositivo .
Quindi, ovviamente, il codice precedente non funzionerà immediatamente.

Per risolvere questo problema, puoi semplicemente utilizzare la nuova nativeBoundsproprietà, invece di bounds, poiché non cambierà con l'orientamento e poiché si basa su una modalità verticale.
Nota che le dimensioni di nativeBoundssono misurate in pixel, quindi per un iPhone 5 l'altezza sarà 1136 invece di 568.

Se scegli anche come target iOS 7 o versioni precedenti, assicurati di utilizzare il rilevamento delle funzionalità, poiché la chiamata nativeBoundsprima di iOS 8 causerà l'arresto anomalo dell'app:

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

È possibile adattare le macro precedenti nel modo seguente:

#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 )

E ovviamente, se devi rilevare un iPhone 6 o 6 Plus, usa le dimensioni dello schermo corrispondenti.


7
Questo è sbagliato, dovrete usare#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser

28
@ H2CO3: Notare che qui il confronto DBL_EPSILONnon è necessario e che il ==confronto non fallirà: è necessario fare il confronto usando le differenze in questo modo se il valore in virgola mobile non può essere espresso come un numero esatto (come 1.0/3.0*3.0ad esempio). Leggi questo articolo per maggiori informazioni;)
AliSoftware

2
questa risposta non è corretta. perché ha ottenuto così tanti pollici in su? non puoi utilizzare solo l'altezza per determinare se è widescreen. amico ...
OMGPOP,

5
Posso aggiungere: Se vuoi che funzioni con il simulatore, usa questo: #define IS_IPHONE (([[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone"]) || ([[[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone Simulator"]))
david

31
Questa risposta è follia. Questa roba sulla raccomandazione di non confrontare questo particolare tipo di float (che in realtà sono - e se sai che Apple dovrebbe sapere che sarà sempre-- numeri interi) con == è una sciocchezza e sovrasta le cose. Inoltre, penso che sia meglio usare UI_USER_INTERFACE_IDIOM () per il rilevamento di iPhone in quanto funziona bene sia sul dispositivo che sul simulatore (e potrebbe essere più veloce dell'approccio UIDevice). Funziona benissimo ed è molto più semplice da leggere: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez

232

Testato e progettato per qualsiasi combinazione di SDK e sistema operativo:

veloce

Aggiunti tipi di iPad. iPad 2 e iPad mini sono iPad non retina. Mentre iPad Mini 2 e versioni successive, iPad 3, 4, iPad Air, Air 2, Air 3 e iPad Pro 9.7 hanno la stessa risoluzione logica di 1024. iPad Pro ha una lunghezza massima di 1366. Riferimento

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

Guardalo in azione https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Nota: se ad esempio iPhone 6 è in modalità ingrandita, l'interfaccia utente è una versione ingrandita di iPhone 5. Queste funzioni non determinano il tipo di dispositivo, ma la modalità di visualizzazione quindi iPhone 5 è il risultato desiderato in questo esempio.

Objective-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)

Utilizzo: http://pastie.org/9687735

Nota: se ad esempio iPhone 6 è in modalità ingrandita, l'interfaccia utente è una versione ingrandita di iPhone 5. Queste funzioni non determinano il tipo di dispositivo, ma la modalità di visualizzazione quindi iPhone 5 è il risultato desiderato in questo esempio.


1
iPhone 5 segnalerà una normale dimensione dello schermo 480x320, senza la nuova immagine predefinita. Per me questo è un comportamento ricercato.
hfossli,

3
Un'aggiunta forse utile è #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)che aiuterà a determinare la differenza tra iPhone4 e iPhone5 e iPad Retina e non retina
bshirley

1
Non sono d'accordo. Penso che la terminologia "widescreen" debba essere esclusa in quanto è rapidamente obsoleta.
hfossli,

1
@Dvole è così che si comporta iOS 8. Utilizzare SCREEN_MAX_LENGTHper ottenere 568 in tutte le rotazioni su iPhone 5.
hfossli

1
@MattParkins Io suggerirei di usare più robusti controlli modello stackoverflow.com/questions/13366976/... .
hfossli,

69

Soluzione davvero semplice

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}

1
haha breve e simpel, ha fatto lo stesso :) balza in alto per mantenere basso il sovraccarico! mettere roba in una macro non è una sfida ...
benjamin.ludwig,

2
Beh, non mettere le cose in macro o funzioni è incline a non essere ASCIUTTO ... Dal momento in cui devi fare questo controllo più di una volta ...
hfossli

Sì, ma definire la macro come mostrato sopra, è più conveniente e facile, non è necessario incollarlo scrivere questo se ... ogni volta.
Resty

Grazie, mi hai salvato la vita: D, ma non so perché Macro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds] .size.height == 568.0) ==> Non funzionava nel simulatore iOS 7.1, prima che sto ancora lavorando su XCode 4.6. OMG iOS 7.1 e Xcode 5
Linh Nguyen

risposta aggiornata di seguito per tenere conto delle dimensioni dello schermo di iPhone 6 e 6 plus
Sam B,

28

Ora dobbiamo tenere conto delle dimensioni dello schermo di iPhone 6 e 6Plus. Ecco una risposta aggiornata

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
}

Alcune informazioni utili

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"

semplicemente non funziona per me iPhone 5 deciso come 4 iPhone 6+ non ha deciso affatto Oh ho capito che sono in orizzontale dovrei cambiare altezza con larghezza :)
ColdSteel

se la tua app è in modalità orizzontale, assicurati di modificare result.height in result.width
Sam B

hmm .. su iPhone 4 (iOS 6.0) non è stato scambiato :( potrebbe essere iOS 6.0 prob o un iPhone 4?
ColdSteel

Ok, ho controllato la vista scambiata solo in iOS 8 e
versioni successive

iPhone 6 dando altezza = 568
MaxEcho

15

Mi sono preso la libertà di mettere la macro di Macmade in una funzione C e di nominarla correttamente perché rileva la disponibilità widescreen e NON necessariamente l'iPhone 5.

Inoltre, la macro non rileva l'esecuzione su un iPhone 5 nel caso in cui il progetto non includa Default-568h@2x.png . Senza la nuova immagine predefinita, l'iPhone 5 segnalerà una normale dimensione dello schermo 480x320 (in punti). Quindi il controllo non è solo per la disponibilità del widescreen ma anche per l' attivazione della modalità widescreen .

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}

Preferisco ancora le macro, per motivi di prestazioni. Si prega di vedere la modifica alla mia risposta. Controlla anche il modello.
Macmade il

1
Hai anche ragione a dire che un iPhone 5 riporterà una normale dimensione dello schermo 480x320, senza la nuova immagine predefinita. Ma penso che non abbia senso rilevare un iPhone 5 in un'app non ottimizzata. :)
Macmade

@Macmade In effetti, non ha senso, ma è bene tenere presente che il rilevamento non funziona. Inoltre, le funzioni possono essere inlined. Saranno anche indicati dove l'ottimizzatore del compilatore pensa che sia una buona idea e dove può sapere che è consentito (ad es. La funzione è nello stesso modulo). L'implementazione di cose come questa tramite una funzione a volte può comportare un ulteriore controllo del tipo.
Ivan Vučica,

4
La domanda relativa alle prestazioni è: perché eseguire questo controllo migliaia di volte durante il ciclo di rendering? Altrimenti, le prestazioni sono un problema e una chiarezza ed evitano effetti collaterali di maggiore importanza.
LearnCocos2D,

Ti ho dato un +1 per questo perché mi piace la funzione separata piuttosto che una macro, ma devo sottolineare che non è davvero corretta o completa. Per rilevare il widescreen, non guardare l'altezza dello schermo. Invece, osserva le proporzioni e ritorna vero solo se le proporzioni sono maggiori o uguali a 16: 9.
Todd Lehman,

11

Ecco i nostri codici, test passati su ios7 / ios8 per iphone4, iphone5, ipad, iphone6, iphone6p, non importa su dispositivi o simulatore:

#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 )

Sto testando su un iPhone 6P e la mia dichiarazione if sta cadendo nella condizione IS_IPHONE_5? Come può essere, il tuo codice sembra buono? Ho fatto una copia e incolla diretta con un semplice if / else e so che il mio telefono è un 6 plus con iOS 8.3.
whyoz,

7

Ho usato la risposta di Hfossli e l'ho tradotta in Swift

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)

6

questa è la macro per il mio progetto cocos2d. dovrebbe essere lo stesso per altre app.

#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))

5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}

3

In Swift, progetto iOS 8+ mi piace fare un'estensione UIScreen, come:

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

}

(NOTA: nativeBoundsè in pixel).

E quindi il codice sarà come:

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

Quindi il codice chiarisce che si tratta di un controllo per la schermata principale, non per il modello del dispositivo.


2

Prendendo in prestito dalla risposta di Samrat Mazumdar, ecco un breve metodo per stimare le dimensioni dello schermo del dispositivo. Funziona con i dispositivi più recenti, ma potrebbe non funzionare su quelli futuri (come tutti i metodi di indovinare potrebbero). Verrà anche confuso se il dispositivo viene specchiato (restituisce le dimensioni dello schermo del dispositivo, non le dimensioni dello schermo speculare)

#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
    }
} 

Ha bisogno di una revisione per iPad mini che, non credo che sarai in grado di determinare in questo maniero.
Daniel,

Sì, iPad mini ha la stessa risoluzione dell'iPad2, quindi questo metodo non funziona per questo. Non sono sicuro di come gestire quel caso in questo momento ...
Jeff Hay,

1
Non dovresti. È possibile controllare l'identificatore del dispositivo per "iPad 2,5" acquistare anche è necessario controllare per 2,6 e 2,7 - la versione solo wifi, GSM e CDMA. Ciò significa che il prossimo iPad mini verrà rilasciato e dovrai aggiornare il codice hard anche a quegli identificatori che non puoi conoscere prima. Non puoi sapere continuamente quando sei su un iPad mini perché in realtà non dovresti provare a "ottimizzare" per lo schermo più piccolo
Daniel

2

Penso che dovrebbe essere buono se questa macro funzionerà in dispositivo e simulatore, di seguito sono la soluzione.

#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)

2

Ho scoperto che le risposte non includono un caso speciale per i simulatori.

#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 )

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;

}

iPhone5 = FALSE;non è necessario perché la variabile ha già quel valore se non viene cambiata
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

     }


1

In questo modo è possibile rilevare la famiglia di dispositivi.

    #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

1

Se il progetto viene creato utilizzando Xcode 6, utilizzare il codice sotto indicato per rilevare i dispositivi.

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");
}

Se il progetto è stato creato in Xcode 5 e aperto in Xcode 6, utilizzare il codice sotto indicato per rilevare i dispositivi (questo codice funziona se non sono assegnate immagini di avvio per iPhone 6,6+)

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

Se stai ancora utilizzando Xcode 5 tutti insieme, utilizza il seguente codice per rilevare i dispositivi (iPhone 6 e 6+ non verranno rilevati)

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");

}

1
  1. Aggiungi un 'Nuovo file Swift' -> AppDelegateEx.swift

  2. aggiungi un'estensione a 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. utilizzo:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }

1

In Swift 3 puoi usare la mia semplice classe KRDeviceType.

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

È ben documentato e supporta gli operatori ==,> =, <=.

Ad esempio per rilevare se il dispositivo ha limiti di iPhone 6 / 6s / 7, puoi semplicemente usare il prossimo confronto:

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

Per rilevare se il dispositivo ha limiti di iPhone 5 / 5S / SE o precedenti (iPhone 4s) puoi utilizzare il confronto successivo:

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

1

Questa è stata risposta centinaia di volte, ma questa soluzione ha funzionato al meglio per me e mi ha aiutato a risolvere il problema quando sono stati introdotti nuovi dispositivi e non ho una dimensione definita.

Swift 5 Helper:

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

Questo perché è facile memorizzare le dimensioni in pollici di un telefono, ad esempio un dispositivo da "5,5 pollici" o "4,7 pollici", ma è difficile ricordare le dimensioni esatte dei pixel.

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

Questo ti dà anche l'opportunità di fare qualcosa del genere:

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

L' impostazione predefinita: tenta di utilizzare le dimensioni e la scala dello schermo per provare a calcolare i pollici diagonali. Questo nel caso in cui compaia una nuova dimensione del dispositivo, farà del suo meglio per determinare e il codice, come l'ultimo esempio, dovrebbe ancora funzionare.


0

utilizzare il seguente codice:

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
}

0

Ecco il test corretto del dispositivo, senza dipendere dall'orientamento

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

-2

Utilizzato per rilevare dispositivi iPhone e iPad di tutti i versetti.

#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) 

iPhone 6 non ha display Retina?
vikingosegundo,

iPhone6 ​​ha il display ratina (@ 2X). e iPhone6 ​​plus ha il display HD (@ 3X).
Vaibhav Sharma,

Quindi, se testato IS_RETINAsu un iPhone 6 plus, viene eseguito il codice 1x?
vikingosegundo,


1
non lo capisci: le tue regole cederanno @1x, dove dovrebbero cedere @3x. comunque: come stai semplicemente copiando e incollando: -1
vikingosegundo
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.