Comment détecter l'iPhone 5 (appareils à écran large)?

300

Je viens de passer à XCode 4.5 GM et j'ai découvert que vous pouvez désormais appliquer la taille '4 "Retina' à votre contrôleur de vue dans le storyboard.

Maintenant, si je veux créer une application qui s'exécute à la fois sur iPhone 4 et 5, bien sûr, je dois créer chaque fenêtre deux fois, mais je dois également détecter si l'utilisateur a un iPhone avec un écran de 3,5 "ou 4", puis appliquer le vue.

Comment dois-je faire ça?

Finn Gaida
la source
2
Vous n'avez pas à créer deux fois chaque "fenêtre". Seuls ceux qui sont censés correspondre exactement à la taille de l'écran devront être relayés. La solution semble assez évidente, il suffit de vérifier les dimensions de la fenêtre et d'ajouter une décision de cas en fonction de la taille retournée.
jusqu'au
1
Eh bien, fondamentalement, c'est vrai, mais je veux utiliser la taille d'écran supplémentaire d'une manière complètement différente, comme vous pourriez le faire avec un écran paysage.
Finn Gaida
Vérifiez cette URL: stackoverflow.com/questions/4779221/…
ios_av
Cette question doit-elle être mise à jour en fonction des nouveaux appareils? Par exemple, "Comment détecter un appareil iOS par la taille de l'écran"?
hfossli

Réponses:

467

Tout d'abord, vous ne devez pas reconstruire toutes vos vues pour s'adapter à un nouvel écran, ni utiliser des vues différentes pour différentes tailles d'écran.

Utilisez les capacités de redimensionnement automatique d'iOS pour que vos vues puissent s'ajuster et adapter n'importe quelle taille d'écran.

Ce n'est pas très difficile, lisez quelques documents à ce sujet. Cela vous fera gagner beaucoup de temps.

iOS 6 propose également de nouvelles fonctionnalités à ce sujet.
Assurez-vous de lire le journal des modifications de l'API iOS 6 sur le site Web des développeurs Apple.
Et vérifiez les nouvelles capacités de mise en page automatique iOS 6 .

Cela dit, si vous avez vraiment besoin de détecter l'iPhone 5, vous pouvez simplement vous fier à la taille de l' écran .

[ [ UIScreen mainScreen ] bounds ].size.height

L'écran de l'iPhone 5 a une hauteur de 568.
Vous pouvez imaginer une macro, pour simplifier tout cela:

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

L'utilisation de fabsavec l'epsilon est là pour éviter les erreurs de précision, lors de la comparaison des virgules flottantes, comme indiqué dans les commentaires de H2CO3.

Vous pouvez donc désormais l'utiliser dans les instructions if / else standard:

if( IS_IPHONE_5 )
{}
else
{}

Modifier - Meilleure détection

Comme indiqué par certaines personnes, cela ne détecte qu'un écran large , pas un véritable iPhone 5.

Les prochaines versions de l'iPod touch auront peut-être également un tel écran, nous pouvons donc utiliser un autre ensemble de macros.

Renommons la macro d'origine IS_WIDESCREEN:

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

Et ajoutons des macros de détection de modèle:

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

De cette façon, nous pouvons nous assurer que nous avons un modèle iPhone ET un écran large, et nous pouvons redéfinir la IS_IPHONE_5macro:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Notez également que, comme indiqué par @ LearnCocos2D, ces macros ne fonctionneront pas si l'application n'est pas optimisée pour l'écran de l'iPhone 5 (sans l'image [email protected]), car la taille de l'écran sera toujours de 320x480 dans un tel un cas.

Je ne pense pas que cela puisse être un problème, car je ne vois pas pourquoi nous voudrions détecter un iPhone 5 dans une application non optimisée.

IMPORTANT - Prise en charge d'iOS 8

Sur iOS 8, la boundspropriété de la UIScreenclasse reflète désormais l' orientation du périphérique .
Donc, évidemment, le code précédent ne fonctionnera pas hors de la boîte.

Pour résoudre ce problème, vous pouvez simplement utiliser la nouvelle nativeBoundspropriété, au lieu de bounds, car elle ne changera pas avec l'orientation, et car elle est basée sur un mode portrait-up.
Notez que les dimensions de nativeBoundssont mesurées en pixels, donc pour un iPhone 5, la hauteur sera de 1136 au lieu de 568.

Si vous ciblez également iOS 7 ou une version nativeBoundsantérieure , assurez-vous d'utiliser la détection des fonctionnalités, car les appels avant iOS 8 planteront votre application:

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

Vous pouvez adapter les macros précédentes de la manière suivante:

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

Et évidemment, si vous devez détecter un iPhone 6 ou 6 Plus, utilisez les tailles d'écran correspondantes.

Macmade
la source
7
C'est faux, vous devrez utiliser#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser
28
@ H2CO3: Notez que la comparaison avec DBL_EPSILONn'est pas nécessaire ici, et que la ==comparaison n'échouera pas : il est seulement nécessaire de faire une comparaison en utilisant des différences de cette façon si la valeur en virgule flottante ne peut pas être exprimée en nombre exact (comme 1.0/3.0*3.0par exemple). Lisez cet article pour plus d'informations;)
AliSoftware
2
cette réponse n'est pas correcte. pourquoi at-il obtenu autant de pouces vers le haut? vous ne pouvez pas utiliser uniquement la hauteur pour déterminer s'il s'agit d'un écran large. mec ...
OMGPOP
5
Puis-je ajouter: Si vous voulez que cela fonctionne avec le simulateur, utilisez ceci: #define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString: @ "iPhone"])) || ([[[UIDevice currentDevice] model] isEqualToString: @ "iPhone Simulator"]))
david
31
Cette réponse est de la folie. Ce truc sur la recommandation de ne pas comparer ce type particulier de flotteurs (qui sont en réalité - et si vous savez qu'Apple devrait savoir que ce sera toujours-- des entiers) avec == est un non-sens et complique les choses. En outre, je pense qu'il est préférable d'utiliser UI_USER_INTERFACE_IDIOM () pour la détection d'iPhone car cela fonctionne bien à la fois sur l'appareil et le simulateur (et cela pourrait être plus rapide que l'approche UIDevice). Cela fonctionne très bien et est beaucoup plus simple à lire: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez
232

Testé et conçu pour toute combinaison de SDK et OS:

Rapide

Types d'iPad ajoutés. L'iPad 2 et l'iPad mini sont des iPad sans rétine. Alors que l'iPad Mini 2 et supérieur, l'iPad 3, 4, l'iPad Air, l'Air 2, l'Air 3 et l'iPad Pro 9.7 ont la même résolution logique de 1024. L'iPad Pro a une longueur maximale de 1366. Référence

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

Voyez-le en action https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Remarque: Si, par exemple, l'iPhone 6 est en mode zoom, l'interface utilisateur est une version agrandie de l'iPhone 5. Ces fonctions ne déterminent pas le type d'appareil, mais le mode d'affichage ainsi l'iPhone 5 est le résultat souhaité dans cet exemple.

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

Utilisation: http://pastie.org/9687735

Remarque: Si, par exemple, l'iPhone 6 est en mode zoom, l'interface utilisateur est une version agrandie de l'iPhone 5. Ces fonctions ne déterminent pas le type d'appareil, mais le mode d'affichage ainsi l'iPhone 5 est le résultat souhaité dans cet exemple.

hfossli
la source
1
L'iPhone 5 affichera une taille d'écran de 480 x 320, sans la nouvelle image par défaut. Pour moi, c'est un comportement recherché.
hfossli
3
Un ajout peut-être utile est celui #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)qui aidera à déterminer la différence entre iPhone4 et iPhone5 et iPad Retina et non-
rétina
1
Je ne suis pas d'accord. Je pense que la terminologie «écran large» doit être laissée de côté car elle est rapidement dépassée.
hfossli
1
@Dvole c'est ainsi que se comporte iOS 8. Utilisez SCREEN_MAX_LENGTHpour obtenir 568 dans toutes les rotations sur iPhone 5.
hfossli
1
@MattParkins Je suggère d'utiliser des vérifications de modèle plus robustes stackoverflow.com/questions/13366976/… .
hfossli
69

Solution vraiment simple

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
la source
1
haha court et simpel, a fait la même chose :) bat pour garder les frais généraux bas! mettre des trucs dans une macro n'est pas un défi ...
benjamin.ludwig
2
Eh bien, ne pas mettre les choses en macro ou les fonctions est susceptible de ne pas être SEC ... A partir du moment où vous devez faire cette vérification plus d'une fois ...
hfossli
Oui, mais définir la macro comme indiqué ci-dessus, est plus pratique et facile, vous n'avez pas besoin de coller, écrivez ceci si ... à chaque fois.
Resty
Merci, vous m'avez sauvé la vie: D, mais je ne sais pas pourquoi Macro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds] .size.height == 568.0) ==> Ne fonctionnait pas dans le simulateur iOS 7.1, avant que je travaille toujours sur XCode 4.6. OMG iOS 7.1 & Xcode 5
Linh Nguyen
mise à jour de la réponse ci-dessous pour prendre en compte les tailles d'écran de l'iPhone 6 et 6 plus
Sam B
28

Nous devons maintenant tenir compte des tailles d'écran de l'iPhone 6 et 6Plus. Voici une réponse mise à jour

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
}

Quelques infos utiles

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
la source
il est juste ne fonctionne pas pour moi l' iPhone 5 a décidé que 4 iPhone 6+ n'a pas décidé du tout Oh , je l' ai , je suis dans le paysage que je devrais changer la hauteur avec une largeur :)
ColdSteel
si votre application est en mode paysage, assurez-vous de changer result.height en result.width
Sam B
hmm .. sur iPhone 4 (iOS 6.0), il n'a pas été échangé :( pourrait être un problème iOS 6.0 ou un iPhone 4?
ColdSteel
D'accord, j'ai vérifié la vue échangée uniquement dans iOS 8 et supérieur
ColdSteel
iPhone 6 donnant une hauteur = 568
MaxEcho
15

J'ai pris la liberté de mettre la macro de Macmade dans une fonction C, et de la nommer correctement car elle détecte la disponibilité des écrans larges et PAS nécessairement l'iPhone 5.

La macro ne détecte pas non plus l'exécution sur un iPhone 5 dans le cas où le projet n'inclut pas le [email protected] . Sans la nouvelle image par défaut, l'iPhone 5 affichera une taille d'écran 480x320 normale (en points). Ainsi, la vérification n'est pas seulement pour la disponibilité de l'écran large, mais aussi pour le mode écran large .

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}
LearnCocos2D
la source
Je préfère toujours les macros, pour des raisons de performances. Veuillez voir la modification de ma réponse. Il vérifie également le modèle.
Macmade
1
Vous avez également raison de dire qu'un iPhone 5 affichera une taille d'écran 480x320 normale, sans la nouvelle image par défaut. Mais je pense qu'il est inutile de détecter un iPhone 5 dans une application non optimisée. :)
Macmade
@Macmade En effet, cela ne sert à rien, mais il est bon de garder à l'esprit que la détection ne fonctionne pas. De plus, les fonctions peuvent être inlined. Ils seront également indiqués là où l'optimiseur du compilateur pense que c'est une bonne idée et où il peut savoir que c'est permis (par exemple, la fonction est dans le même module). Implémenter des trucs comme ça via une fonction peut parfois apporter une vérification de type supplémentaire.
Ivan Vučica
4
La question liée aux performances est la suivante: pourquoi exécuter cette vérification des milliers de fois pendant votre boucle de rendu? Sinon, la performance n'est pas un problème et la clarté et évite les effets secondaires de plus grande importance.
LearnCocos2D
Je vous ai donné un +1 pour cela parce que j'aime la fonction séparée plutôt qu'une macro, mais je dois souligner qu'elle n'est pas vraiment correcte ou complète. Pour détecter un écran large, ne regardez pas la hauteur de l'écran. Au lieu de cela, regardez le rapport d'aspect et ne retournez vrai que si le rapport d'aspect est supérieur ou égal à 16: 9.
Todd Lehman
11

Voici nos codes, test réussi sur ios7 / ios8 pour iphone4, iphone5, ipad, iphone6, iphone6p, peu importe sur les appareils ou le simulateur:

#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 )
Gingembre
la source
Je teste sur un iPhone 6P et mon instruction if tombe dans la condition IS_IPHONE_5? Comment cela peut-il être, votre code semble bon? J'ai fait un simple copier-coller avec un simple if / else et je sais que mon téléphone est un 6 plus exécutant iOS 8.3.
whyoz
7

J'ai utilisé la réponse de hfossli et l'ai traduite en 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)
Borbea
la source
6

c'est la macro de mon projet cocos2d. devrait être le même pour les autres applications.

#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
la source
5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}
D-eptdeveloper
la source
3

Dans Swift, le projet iOS 8+ sur lequel j'aime faire une extension UIScreen, comme:

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

}

(REMARQUE: nativeBoundsest en pixels).

Et puis le code sera comme:

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

Le code indique donc clairement qu'il s'agit d'une vérification de l'écran principal, et non du modèle de l'appareil.

zubko
la source
2

Empruntant à la réponse de Samrat Mazumdar, voici une courte méthode qui estime la taille de l'écran de l'appareil. Il fonctionne avec les derniers appareils, mais peut échouer sur les futurs (comme toutes les méthodes de devinettes). Cela deviendra également confus si l'appareil est en miroir (renvoie la taille de l'écran de l'appareil, pas la taille de l'écran en miroir)

#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
la source
A besoin d'une révision pour iPad mini qui, je ne pense pas que vous serez en mesure de déterminer dans ce manoir.
Daniel
Oui, l'iPad mini a la même résolution que l'iPad2, donc cette méthode ne fonctionne pas pour cela. Je ne sais pas comment gérer cette affaire en ce moment ...
Jeff Hay
1
Tu n'es pas censé le faire. Vous pouvez vérifier l'identifiant de l'appareil pour "iPad 2,5" acheter également vous devez vérifier pour 2,6 et 2,7 - la version wifi uniquement, gsm et CDMA. Mais cela signifie que le prochain iPad mini sera publié et que vous devrez également mettre à jour le code dur vers ces identifiants que vous ne pouvez pas connaître à l'avance. Vous ne pouvez pas savoir en permanence quand vous êtes sur un iPad mini parce que vous ne devriez vraiment pas essayer "d'optimiser" pour le petit écran
Daniel
2

Je pense que cela devrait être bien si cette macro fonctionne dans l'appareil et le simulateur, voici la solution.

#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
la source
2

J'ai trouvé que les réponses n'incluent pas de cas spécial pour les simulateurs.

#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 )
valvoline
la source
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
la source
iPhone5 = FALSE;est inutile car la variable a déjà cette valeur si elle n'est pas modifiée
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
la source
1

Se fier à la taille est faux à tant de niveaux. Et si on demandait au système?

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

Tiré de la meilleure façon de détecter le type de matériel, iPhone4 ou iPhone5? , réponse edzio27.

3d0
la source
1

De cette façon, vous pouvez détecter la famille d'appareils.

    #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
la source
1

Si le projet est créé à l'aide de Xcode 6, utilisez le code mentionné ci-dessous pour détecter les périphériques.

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

Si le projet a été créé dans Xcode 5 et ouvert dans Xcode 6, utilisez le code mentionné ci-dessous pour détecter les appareils (ce code fonctionne si aucune image de lancement pour iPhone 6,6+ n'est affectée)

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

Si vous utilisez toujours Xcode 5 tous ensemble, utilisez le code suivant pour détecter les appareils (l'iPhone 6 et 6+ ne sera pas détecté)

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
la source
1
  1. Ajouter un «nouveau fichier Swift» -> AppDelegateEx.swift

  2. ajouter une extension à 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. usage:

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

Dans Swift 3, vous pouvez utiliser ma classe simple KRDeviceType.

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

Il est bien documenté et prend en charge les opérateurs ==,> =, <=.

Par exemple, pour détecter si l'appareil a des limites d'iPhone 6 / 6s / 7, vous pouvez simplement utiliser la comparaison suivante:

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

Pour détecter si l'appareil a des limites d'iPhone 5 / 5S / SE ou antérieur (iPhone 4s), vous pouvez utiliser la comparaison suivante:

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

Cela a été répondu une centaine de fois, mais cette solution a fonctionné le mieux pour moi et a aidé à résoudre le problème lorsque de nouveaux appareils sont introduits et que je n'ai pas de taille définie.

Aide de Swift 5:

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

En effet, il est facile de mémoriser les tailles en pouces d'un téléphone, comme un appareil "5,5 pouces" ou "4,7 pouces", mais il est difficile de se souvenir des tailles de pixels exactes.

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

Cela vous donne également la possibilité de faire quelque chose comme ceci:

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

La valeur par défaut: essaie d'utiliser la taille et l'échelle de l'écran pour essayer de calculer les pouces diagonaux. Dans le cas où une nouvelle taille d'appareil apparaît, il fera de son mieux pour déterminer et le code, comme le dernier exemple, devrait toujours fonctionner.

William T.
la source
0

utilisez le code suivant:

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
la source
0

Voici le test correct de l'appareil, sans dépendre de l'orientation

- (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
la source
-2

Utilisé pour détecter les appareils iPhone et iPad de tous les versons.

#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
la source
L'iPhone 6 n'a pas d'affichage de rétine?
vikingosegundo
L'iPhone6 ​​dispose de l'écran ratina (@ 2X). et l'iPhone6 ​​plus dispose d'un écran HD (@ 3X).
Vaibhav Sharma
Donc, si testé IS_RETINAsur un iPhone 6 plus, 1x code est exécuté?
vikingosegundo
Voir ce lien. stackoverflow.com/questions/25756589/…
Vaibhav Sharma
1
vous ne l'obtenez pas: vos règles vont céder @1xlà où elles devraient céder @3x. de toute façon: comme vous êtes simplement en
train de